001/*
002 * JPPF.
003 * Copyright (C) 2005-2018 JPPF Team.
004 * http://www.jppf.org
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.jppf.node.protocol;
020
021import org.jppf.node.policy.ExecutionPolicy;
022import org.jppf.scheduling.JPPFSchedule;
023
024
025/**
026 * This interface represents the Service Level Agreement between a JPPF job and a server.
027 * It determines the state, conditions and order in which a job will be executed.
028 * @author Laurent Cohen
029 */
030public class JobSLA extends JobCommonSLA<JobSLA> {
031  /**
032   * Explicit serialVersionUID.
033   */
034  private static final long serialVersionUID = 1L;
035  /**
036   * The maximum number of nodes this job can run on.
037   */
038  private int maxNodes = Integer.MAX_VALUE;
039  /**
040   * The maximum number of groups of master/slave nodes the job can be executed on at any given time.
041   * <p>This setting means that the job can only be executed on at most {@code maxMasterNodeGroups} master nodes and all their slaves.
042   */
043  private int maxNodeProvisioningGroups = Integer.MAX_VALUE;
044  /**
045   * The priority of this job, used by the server to prioritize queued jobs.
046   */
047  private int priority = 0;
048  /**
049   * Determines whether this job is initially suspended.
050   * If it is, it will have to be resumed, using either the admin console or the JMX APIs.
051   */
052  private boolean suspended = false;
053  /**
054   * Specifies whether the job is a broadcast job.
055   */
056  private boolean broadcastJob = false;
057  /**
058   * Determines whether the job should be canceled by the driver if the client gets disconnected.
059   */
060  private boolean cancelUponClientDisconnect = true;
061  /**
062   * Get the name of the strategy used to return the results back to the client.
063   */
064  private String resultsStrategy = null;
065  /**
066   * The classpath associated with the job.
067   */
068  private ClassPath classPath = new ClassPathImpl();
069  /**
070   * The expiration schedule for any subset of the job dispatched to a node.
071   */
072  private JPPFSchedule dispatchExpirationSchedule;
073  /**
074   * The number of times a dispatched task can expire before it is finally cancelled.
075   */
076  private int maxDispatchExpirations = 0;
077  /**
078   * Maximum number of times a task can rsubmit itself via {@link org.jppf.node.protocol.AbstractTask#setResubmit(boolean) AbstractTask.setResubmit(boolean)}.
079   */
080  private int maxTaskResubmits = 1;
081  /**
082   * Whether the max resubmits limit for tasks is also applied when tasks are resubmitted due to a node error.
083   */
084  private boolean applyMaxResubmitsUponNodeError = false;
085  /**
086   * Whether remote class loading is enabled for the job.
087   */
088  private boolean remoteClassLoadingEnabled = true;
089  /**
090   * The global execution policy which applies to the driver only.
091   */
092  private ExecutionPolicy gridExecutionPolicy;
093  /**
094   * The configuration of the node(s) this job should be executed on.
095   */
096  private JPPFNodeConfigSpec nodeConfigurationSpec;
097  /**
098   * Whether this job is persisted by the driver and behavior upon recovery.
099   */
100  private PersistenceSpec persistenceSpec = new PersistenceSpec();
101
102  /**
103   * Default constructor.
104   */
105  public JobSLA() {
106  }
107
108  /**
109   * Get the priority of this job.
110   * @return the priority as an int.
111   */
112  public int getPriority() {
113    return priority;
114  }
115
116  /**
117   * Set the priority of this job.
118   * @param priority the priority as an int.
119   * @return this SLA, for mathod chaining.
120   */
121  public JobSLA setPriority(final int priority) {
122    this.priority = priority;
123    return this;
124  }
125
126  /**
127   * Get the maximum number of nodes this job can run on.
128   * @return the number of nodes as an int value.
129   */
130  public int getMaxNodes() {
131    return maxNodes;
132  }
133
134  /**
135   * Set the maximum number of nodes this job can run on.
136   * @param maxNodes the number of nodes as an int value. A value <= 0 means no limit on the number of nodes.
137   * @return this SLA, for mathod chaining.
138   */
139  public JobSLA setMaxNodes(final int maxNodes) {
140    this.maxNodes = maxNodes > 0 ? maxNodes : Integer.MAX_VALUE;
141    return this;
142  }
143
144  /**
145   * Get the maximum number of groups of master/slaves nodes the job can be executed on at any given time.
146   * <p>This setting means that the job can only be executed on at most {@code maxMasterNodeGroups} master nodes and all their slaves.
147   * @return the number of nodes as an int value.
148   * @since 5.1
149   */
150  public int getMaxNodeProvisioningGroupss() {
151    return maxNodeProvisioningGroups;
152  }
153
154  /**
155   * Set the maximum number of groups of master/slaves nodes the job can be executed on at any given time.
156   * <p>This setting means that the job can only be executed on at most {@code maxMasterNodeGroups} master nodes and all their slaves.
157   * @param maxNodeProvisioningGroups the number of nodes as an int value. A value <= 0 means no limit on the number of nodes.
158   * Any value <= 0 will be ignored.
159   * @return this SLA, for mathod chaining.
160   * @since 5.1
161   */
162  public JobSLA setMaxNodeProvisioningGroups(final int maxNodeProvisioningGroups) {
163    if (maxNodeProvisioningGroups > 0) this.maxNodeProvisioningGroups = maxNodeProvisioningGroups;
164    return this;
165  }
166
167  /**
168   * Determine whether this job is initially suspended.
169   * @return true if the job is suspended, false otherwise.
170   */
171  public boolean isSuspended() {
172    return suspended;
173  }
174
175  /**
176   * Specify whether this job is initially suspended.
177   * @param suspended true if the job is suspended, false otherwise.
178   * @return this SLA, for mathod chaining.
179   */
180  public JobSLA setSuspended(final boolean suspended) {
181    this.suspended = suspended;
182    return this;
183  }
184
185  /**
186   * Determine whether the job is a broadcast job.
187   * @return true for a broadcast job, false otherwise.
188   */
189  public boolean isBroadcastJob() {
190    return broadcastJob;
191  }
192
193  /**
194   * Specify whether the job is a broadcast job.
195   * @param broadcastJob true for a broadcast job, false otherwise.
196   * @return this SLA, for mathod chaining.
197   */
198  public JobSLA setBroadcastJob(final boolean broadcastJob) {
199    this.broadcastJob = broadcastJob;
200    return this;
201  }
202
203  /**
204   * Determine whether the job should be canceled by the driver if the client gets disconnected.
205   * @return <code>true</code> if the job should be canceled (this is the default), <code>false</code> otherwise.
206   */
207  public boolean isCancelUponClientDisconnect() {
208    return cancelUponClientDisconnect;
209  }
210
211  /**
212   * Specify whether the job should be canceled by the driver if the client gets disconnected.
213   * @param cancelUponClientDisconnect <code>true</code> if the job should be canceled, <code>false</code> otherwise.
214   * @return this SLA, for mathod chaining.
215   */
216  public JobSLA setCancelUponClientDisconnect(final boolean cancelUponClientDisconnect) {
217    this.cancelUponClientDisconnect = cancelUponClientDisconnect;
218    return this;
219  }
220
221  /**
222   * Get the strategy used to return the results back to the client.
223   * @return the name of the strategy to use.
224   * @exclude
225   */
226  public String getResultsStrategy() {
227    return resultsStrategy;
228  }
229
230  /**
231   * Set the strategy used to return the results back to the client.
232   * @param name the name of the strategy to use.
233   * @return this SLA, for mathod chaining.
234   * @exclude
235   */
236  public JobSLA setResultsStrategy(final String name) {
237    this.resultsStrategy = name;
238    return this;
239  }
240
241  /**
242   * Get the class path associated with the job.
243   * @return an instance of {@link ClassPath}.
244   */
245  public ClassPath getClassPath() {
246    return classPath;
247  }
248
249  /**
250   * Set the class path associated with the job.
251   * @param classpath an instance of {@link ClassPath}.
252   * @return this SLA, for mathod chaining.
253   */
254  public JobSLA setClassPath(final ClassPath classpath) {
255    if (classpath == null) throw new IllegalArgumentException("classpath cannot be null");
256    this.classPath = classpath;
257    return this;
258  }
259
260  /**
261   * Get the expiration schedule for any subset of the job dispatched to a node.
262   * @return a {@link JPPFSchedule} instance.
263   */
264  public JPPFSchedule getDispatchExpirationSchedule() {
265    return dispatchExpirationSchedule;
266  }
267
268  /**
269   * Set the expiration schedule for any subset of the job dispatched to a node.
270   * @param schedule a {@link JPPFSchedule} instance.
271   * @return this SLA, for mathod chaining.
272   */
273  public JobSLA setDispatchExpirationSchedule(final JPPFSchedule schedule) {
274    this.dispatchExpirationSchedule = schedule;
275    return this;
276  }
277
278  /**
279   * Get the number of times a dispatched task can expire before it is finally cancelled.
280   * @return the number of expirations as an int.
281   */
282  public int getMaxDispatchExpirations() {
283    return maxDispatchExpirations;
284  }
285
286  /**
287   * Set the number of times a dispatched task can expire before it is finally cancelled.
288   * @param max the number of expirations as an int.
289   * @return this SLA, for mathod chaining.
290   */
291  public JobSLA setMaxDispatchExpirations(final int max) {
292    this.maxDispatchExpirations = max;
293    return this;
294  }
295
296  /**
297   * Get the naximum number of times a task can resubmit itself via {@link org.jppf.node.protocol.AbstractTask#setResubmit(boolean) AbstractTask.setResubmit(boolean)}.
298   * The default value is 1, meaning that a task can resubmit itself at most once.
299   * @return the maximum number of resubmits; a value of 0 or less means tasks in the job cannot be resubmitted.
300   */
301  public int getMaxTaskResubmits() {
302    return maxTaskResubmits;
303  }
304
305  /**
306   * Set the naximum number of times a task can resubmit itself via {@link org.jppf.node.protocol.AbstractTask#setResubmit(boolean) AbstractTask.setResubmit(boolean)}.
307   * @param maxResubmits the maximum number of resubmits; a value of 0 or less means tasks in the job cannot be resubmitted.
308   * @return this SLA, for mathod chaining.
309   */
310  public JobSLA setMaxTaskResubmits(final int maxResubmits) {
311    this.maxTaskResubmits = maxResubmits;
312    return this;
313  }
314
315  /**
316   * Determine whether the max resubmits limit for tasks is also applied when tasks are resubmitted due to a node error.
317   * This flag is false by default.
318   * @return {@code true} if the max resubmits count is applied upon node errors, {@code false} otherwise.
319   * @since 4.2
320   */
321  public boolean isApplyMaxResubmitsUponNodeError() {
322    return applyMaxResubmitsUponNodeError;
323  }
324
325  /**
326   * Specify whether the max resubmits limit for tasks should also be applied when tasks are resubmitted due to a node error.
327   * @param applyMaxResubmitsUponNodeError {@code true} to specify that the max resubmits count is applied upon node errors, {@code false} otherwise.
328   * @return this SLA, for mathod chaining.
329   * @since 4.2
330   */
331  public JobSLA setApplyMaxResubmitsUponNodeError(final boolean applyMaxResubmitsUponNodeError) {
332    this.applyMaxResubmitsUponNodeError = applyMaxResubmitsUponNodeError;
333    return this;
334  }
335
336  /**
337   * Determine whether remote class loading is enabled for the job.
338   * The default value, when not specified via {@link #setRemoteClassLoadingEnabled(boolean)}, is {@code true}.
339   * @return {@code true} is remote class loading is enabled, {@code false} otherwise.
340   * @since 4.2
341   */
342  public boolean isRemoteClassLoadingEnabled() {
343    return remoteClassLoadingEnabled;
344  }
345
346  /**
347   * Specify whether remote class loading is enabled for the job.
348   * @param enabled {@code true} to enable remote class loading, {@code false} to disable it.
349   * @return this SLA, for mathod chaining.
350   * @since 4.2
351   */
352  public JobSLA setRemoteClassLoadingEnabled(final boolean enabled) {
353    this.remoteClassLoadingEnabled = enabled;
354    return this;
355  }
356
357  /**
358   * Get the global grid execution policy (which applies to the driver).
359   * @return an {@link ExecutionPolicy} object.
360   * @since 5.2
361   */
362  public ExecutionPolicy getGridExecutionPolicy() {
363    return gridExecutionPolicy;
364  }
365
366  /**
367   * Set the global grid execution policy (which applies to the driver).
368   * @param policy an {@link ExecutionPolicy} object.
369   * @return this SLA, for mathod chaining.
370   * @since 5.2
371   */
372  public JobSLA setGridExecutionPolicy(final ExecutionPolicy policy) {
373    this.gridExecutionPolicy = policy;
374    return this;
375  }
376
377  /**
378   * Get the configuration of the node(s) this job should be executed on,
379   * forcing a restart of the node with appropriate configuration overrides if there is no such node.
380   * @return the desired configuration as a {@link JPPFNodeConfigSpec} object.
381   * @since 5.2
382   */
383  public JPPFNodeConfigSpec getDesiredNodeConfiguration() {
384    return nodeConfigurationSpec;
385  }
386
387  /**
388   * Set the configuration of the node(s) this job should be executed on,
389   * forcing a restart of the node with appropriate configuration overrides if there is no such node.
390   * @param nodeConfigurationSpec the desired configuration as a {@link JPPFNodeConfigSpec} object.
391   * @return this SLA, for mathod chaining.
392   * @since 5.2
393   */
394  public JobSLA setDesiredNodeConfiguration(final JPPFNodeConfigSpec nodeConfigurationSpec) {
395    this.nodeConfigurationSpec = nodeConfigurationSpec;
396    return this;
397  }
398
399  /**
400   * Get the specification of the job persistence in the driver.
401   * @return a {@link PersistenceSpec} instance.
402   * @since 6.0
403   */
404  public PersistenceSpec getPersistenceSpec() {
405    return persistenceSpec;
406  }
407
408  /**
409   * Set the specification of the job persistence in the driver.
410   * @param persistenceSpec a {@link PersistenceSpec} instance.
411   */
412  void setPersistenceSpec(final PersistenceSpec persistenceSpec) {
413    this.persistenceSpec = persistenceSpec;
414  }
415
416  /**
417   * Create a copy of this job SLA.
418   * @return a {@link JobSLA} instance.
419   */
420  public JobSLA copy() {
421    final JobSLA sla = new JobSLA();
422    copyTo(sla);
423    sla.setApplyMaxResubmitsUponNodeError(applyMaxResubmitsUponNodeError);
424    sla.setBroadcastJob(broadcastJob);
425    sla.setCancelUponClientDisconnect(cancelUponClientDisconnect);
426    sla.setClassPath(classPath);
427    sla.setDesiredNodeConfiguration(nodeConfigurationSpec);
428    sla.setDispatchExpirationSchedule(dispatchExpirationSchedule);
429    sla.setGridExecutionPolicy(gridExecutionPolicy);
430    sla.setMaxDispatchExpirations(maxDispatchExpirations);
431    sla.setMaxNodeProvisioningGroups(maxNodeProvisioningGroups);
432    sla.setMaxNodes(maxNodes);
433    sla.setMaxTaskResubmits(maxTaskResubmits);
434    sla.setPersistenceSpec(persistenceSpec);
435    sla.setPriority(priority);
436    sla.setRemoteClassLoadingEnabled(remoteClassLoadingEnabled);
437    sla.setResultsStrategy(resultsStrategy);
438    sla.setSuspended(suspended);
439    return sla;
440  }
441}