/*
*
* Copyright 2015 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.netflix.genie.common.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.netflix.genie.common.util.TimeUtils;
import lombok.Getter;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.time.Duration;
import java.util.Date;
import java.util.Optional;
/**
* Read only data transfer object representing a Job in the Genie system.
*
* @author tgianos
* @since 3.0.0
*/
@Getter
@JsonDeserialize(builder = Job.Builder.class)
public class Job extends CommonDTO {
private static final long serialVersionUID = -4218933066048954819L;
@NotNull(message = "A valid job status is required")
private final JobStatus status;
@Size(max = 255, message = "Max length of the status message is 255 characters")
private final String statusMsg;
private final Date started;
private final Date finished;
@Size(max = 1024, message = "Max character length is 1024 characters for the archive location")
private final String archiveLocation;
@Size(max = 255, message = "Max character length is 255 characters for the cluster name")
private final String clusterName;
@Size(max = 255, message = "Max character length is 255 characters for the command name")
private final String commandName;
@NotNull
@JsonSerialize(using = ToStringSerializer.class)
private final Duration runtime;
@Size(min = 1, max = 10000, message = "Command arguments are required and max at 10000 characters")
private String commandArgs;
/**
* Constructor used by the builder.
*
* @param builder The builder to use
*/
protected Job(final Builder builder) {
super(builder);
this.commandArgs = builder.bCommandArgs;
this.status = builder.bStatus;
this.statusMsg = builder.bStatusMsg;
this.started = builder.bStarted == null ? null : new Date(builder.bStarted.getTime());
this.finished = builder.bFinished == null ? null : new Date(builder.bFinished.getTime());
this.archiveLocation = builder.bArchiveLocation;
this.clusterName = builder.bClusterName;
this.commandName = builder.bCommandName;
this.runtime = TimeUtils.getDuration(this.started, this.finished);
}
/**
* Get the current status message.
*
* @return The status message as an optional
*/
public Optional<String> getStatusMsg() {
return Optional.ofNullable(this.statusMsg);
}
/**
* Get the archive location for the job if there is one.
*
* @return The archive location
*/
public Optional<String> getArchiveLocation() {
return Optional.ofNullable(this.archiveLocation);
}
/**
* Get the name of the cluster running the job if there currently is one.
*
* @return The name of the cluster where the job is running
*/
public Optional<String> getClusterName() {
return Optional.ofNullable(this.clusterName);
}
/**
* Get the name of the command running this job if there currently is one.
*
* @return The name of the command
*/
public Optional<String> getCommandName() {
return Optional.ofNullable(this.commandName);
}
/**
* Get the time the job started.
*
* @return The started time or null if not set
*/
public Optional<Date> getStarted() {
return this.started == null ? Optional.empty() : Optional.of(new Date(this.started.getTime()));
}
/**
* Get the time the job finished.
*
* @return The finished time or null if not set
*/
public Optional<Date> getFinished() {
return this.finished == null ? Optional.empty() : Optional.of(new Date(this.finished.getTime()));
}
/**
* A builder to create jobs.
*
* @author tgianos
* @since 3.0.0
*/
public static class Builder extends CommonDTO.Builder<Builder> {
private final String bCommandArgs;
private JobStatus bStatus = JobStatus.INIT;
private String bStatusMsg;
private Date bStarted;
private Date bFinished;
private String bArchiveLocation;
private String bClusterName;
private String bCommandName;
/**
* Constructor which has required fields.
*
* @param name The name to use for the Job
* @param user The user to use for the Job
* @param version The version to use for the Job
* @param commandArgs The command arguments used for this job
*/
public Builder(
@JsonProperty("name")
final String name,
@JsonProperty("user")
final String user,
@JsonProperty("version")
final String version,
@JsonProperty("commandArgs")
final String commandArgs
) {
super(name, user, version);
this.bCommandArgs = commandArgs;
}
/**
* Set the execution cluster name for this job.
*
* @param clusterName The execution cluster name
* @return The builder
*/
public Builder withClusterName(final String clusterName) {
this.bClusterName = clusterName;
return this;
}
/**
* Set the name of the command used to run this job.
*
* @param commandName The name of the command
* @return The builder
*/
public Builder withCommandName(final String commandName) {
this.bCommandName = commandName;
return this;
}
/**
* Set the status of the job.
*
* @param status The status
* @return The builder
* @see JobStatus
*/
public Builder withStatus(final JobStatus status) {
if (status != null) {
this.bStatus = status;
}
return this;
}
/**
* Set the detailed status message of the job.
*
* @param statusMsg The status message
* @return The builder
*/
public Builder withStatusMsg(final String statusMsg) {
this.bStatusMsg = statusMsg;
return this;
}
/**
* Set the started time of the job.
*
* @param started The started time of the job
* @return The builder
*/
public Builder withStarted(final Date started) {
if (started != null) {
this.bStarted = new Date(started.getTime());
}
return this;
}
/**
* Set the finished time of the job.
*
* @param finished The time the job finished
* @return The builder
*/
public Builder withFinished(final Date finished) {
if (finished != null) {
this.bFinished = new Date(finished.getTime());
}
return this;
}
/**
* Set the archive location of the job.
*
* @param archiveLocation The location where the job results are archived
* @return The builder
*/
public Builder withArchiveLocation(final String archiveLocation) {
this.bArchiveLocation = archiveLocation;
return this;
}
/**
* Build the job.
*
* @return Create the final read-only Job instance
*/
public Job build() {
return new Job(this);
}
}
}