From f7316608c467fab84efeda6e48d338074cd657e5 Mon Sep 17 00:00:00 2001 From: Mateusz Warowny Date: Wed, 16 Feb 2022 17:38:12 +0100 Subject: [PATCH] JAL-3878 Add WebServiceJob class. --- src/jalview/ws2/api/JobStatus.java | 62 ++++++++ src/jalview/ws2/client/api/WebServiceJob.java | 190 +++++++++++++++++++++++++ 2 files changed, 252 insertions(+) create mode 100644 src/jalview/ws2/api/JobStatus.java create mode 100644 src/jalview/ws2/client/api/WebServiceJob.java diff --git a/src/jalview/ws2/api/JobStatus.java b/src/jalview/ws2/api/JobStatus.java new file mode 100644 index 0000000..1dabc6b --- /dev/null +++ b/src/jalview/ws2/api/JobStatus.java @@ -0,0 +1,62 @@ +package jalview.ws2.api; + +public enum JobStatus +{ + /** Job has invalid inputs and cannot be started. */ + INVALID, + /** Job is created and ready for submission. */ + READY, + /** Job has been submitted and awaits processing. */ + SUBMITTED, + /** Job has been queued for execution */ + QUEUED, + /** Job is running */ + RUNNING, + /** Job has completed successfully. */ + COMPLETED, + /** Job has finished with errors. */ + FAILED, + /** Job has been cancelled by the user. */ + CANCELLED, + /** Job cannot be processed due to server error. */ + SERVER_ERROR, + /** Job status cannot be determined. */ + UNKNOWN; + + /** + * Returns true if the status corresponds to the job completed due to normal + * termination, error or cancellation. + * + * @return {@value true} if status corresponds to a finished job. + */ + public boolean isDone() + { + switch (this) + { + case COMPLETED: + case FAILED: + case CANCELLED: + case SERVER_ERROR: + return true; + case INVALID: + case READY: + case SUBMITTED: + case QUEUED: + case RUNNING: + case UNKNOWN: + return false; + default: + throw new AssertionError("non-exhaustive switch statement"); + } + } + + public boolean isCompleted() + { + return this == COMPLETED; + } + + public boolean isCancelled() + { + return this == CANCELLED; + } +} diff --git a/src/jalview/ws2/client/api/WebServiceJob.java b/src/jalview/ws2/client/api/WebServiceJob.java new file mode 100644 index 0000000..32fccec --- /dev/null +++ b/src/jalview/ws2/client/api/WebServiceJob.java @@ -0,0 +1,190 @@ +package jalview.ws2.client.api; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.Date; + +import jalview.util.MathUtils; +import jalview.ws2.api.JobStatus; + +/** + * {@code WebServiceJob} represents a job running on a remote server. The object + * contains all the information needed to associate the job with an originating + * client and url, service being run and to poll the job and retrieve the + * results from the server. The {@code WebServiceJob} object is provided by the + * {@link WebServiceClientI#submit} method when the job is created. + * + * @see WebServiceClientI + * + * @author mmwarowny + */ +public class WebServiceJob +{ + /** Unique id used internally by Jalview */ + private final long internalId = MathUtils.getUID(); + + /** Name of the related client */ + private final String serviceClient; + + /** Name of the related service */ + private final String serviceName; + + /** URL the job is valid for */ + private final String url; + + /** External job id as given by the server */ + private final String jobId; + + /** Current status of the job */ + private JobStatus status = JobStatus.READY; + + private String log = ""; + + private String errorLog = ""; + + private Date creationTime = new Date(); + + public WebServiceJob(String serviceClient, String serviceName, + String url, String jobId) + { + this.serviceClient = serviceClient; + this.serviceName = serviceName; + this.url = url; + this.jobId = jobId; + } + + /** + * Get a unique job id used internally by Jalview. + * + * @return unique job id + */ + public long getInternalId() + { + return internalId; + } + + /** + * Get a URL this job originates from. + * + * @return job URL + */ + public String getUrl() + { + return url; + } + + /** + * Get an id assigned to the job by the server. + * + * @return job id handle + */ + public String getJobId() + { + return jobId; + } + + /** + * @return job status + */ + public JobStatus getStatus() + { + return status; + } + + /** + * Update status of the job and notify the listeners. This method should only + * be used by {@link WebServiceClientI} implementations when polling the job. + * + * @param status + * new job status + */ + public void setStatus(JobStatus status) + { + JobStatus oldStatus = this.status; + this.status = status; + pcs.firePropertyChange("status", oldStatus, status); + } + + /** + * @return standard progress log + */ + public String getLog() + { + return log; + } + + /** + * Update log string with data received from the server and notify the + * listeners. This method should only be used by {@link WebServiceClientI} + * implementations when polling the job. + * + * @param log + * new log string + */ + public void setLog(String log) + { + String oldLog = this.log; + this.log = log; + pcs.firePropertyChange("log", oldLog, log); + } + + /** + * @return error log + */ + public String getErrorLog() + { + return errorLog; + } + + /** + * Update error log string with data received from the server and notify the + * listeners. This method should only be used by {@link WebServiceClientI} + * implementations when polling the job + * + * @param errorLog + * new error log string + */ + public void setErrorLog(String errorLog) + { + String oldLog = this.errorLog; + this.errorLog = errorLog; + pcs.firePropertyChange("errorLog", oldLog, errorLog); + } + + /** + * @return Job creation time + */ + public Date getCreationTime() + { + return creationTime; + } + + public String toString() + { + return String.format("%s:%s [%s] Created %s", serviceClient, serviceName, + jobId, creationTime); + } + + /* Methods related to bean listeners */ + private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); + + public void addPropertyChangeListener(PropertyChangeListener listener) + { + pcs.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) + { + pcs.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) + { + pcs.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) + { + pcs.removePropertyChangeListener(propertyName, listener); + } +} -- 1.7.10.2