/*
* ProActive Parallel Suite(TM):
* The Open Source library for parallel and distributed
* Workflows & Scheduling, Orchestration, Cloud Automation
* and Big Data Analysis on Enterprise Grids & Clouds.
*
* Copyright (c) 2007 - 2017 ActiveEon
* Contact: contact@activeeon.com
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation: version 3 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* If needed, contact us to obtain a release under GPL Version 2 or 3
* or a different license than the AGPL.
*/
package org.ow2.proactive.scheduler.rest;
import static java.lang.String.format;
import static java.lang.System.currentTimeMillis;
import static org.ow2.proactive.scheduler.rest.ExceptionUtility.exception;
import static org.ow2.proactive.scheduler.rest.ExceptionUtility.throwJAFEOrUJEOrNCEOrPE;
import static org.ow2.proactive.scheduler.rest.ExceptionUtility.throwNCEOrPE;
import static org.ow2.proactive.scheduler.rest.ExceptionUtility.throwNCEOrPEOrSCEOrJCE;
import static org.ow2.proactive.scheduler.rest.ExceptionUtility.throwUJEOrNCEOrPE;
import static org.ow2.proactive.scheduler.rest.ExceptionUtility.throwUJEOrNCEOrPEOrUTE;
import static org.ow2.proactive.scheduler.rest.data.DataUtility.jobId;
import static org.ow2.proactive.scheduler.rest.data.DataUtility.taskState;
import static org.ow2.proactive.scheduler.rest.data.DataUtility.toJobInfos;
import static org.ow2.proactive.scheduler.rest.data.DataUtility.toJobResult;
import static org.ow2.proactive.scheduler.rest.data.DataUtility.toJobState;
import static org.ow2.proactive.scheduler.rest.data.DataUtility.toJobUsages;
import static org.ow2.proactive.scheduler.rest.data.DataUtility.toSchedulerUserInfos;
import static org.ow2.proactive.scheduler.rest.data.DataUtility.toTaskResult;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.security.KeyException;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.apache.http.client.HttpClient;
import org.apache.log4j.Logger;
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.objectweb.proactive.core.util.log.ProActiveLogger;
import org.ow2.proactive.authentication.ConnectionInfo;
import org.ow2.proactive.db.SortParameter;
import org.ow2.proactive.http.HttpClientBuilder;
import org.ow2.proactive.scheduler.common.JobFilterCriteria;
import org.ow2.proactive.scheduler.common.JobSortParameter;
import org.ow2.proactive.scheduler.common.Page;
import org.ow2.proactive.scheduler.common.SchedulerEvent;
import org.ow2.proactive.scheduler.common.SchedulerEventListener;
import org.ow2.proactive.scheduler.common.SchedulerStatus;
import org.ow2.proactive.scheduler.common.SortSpecifierContainer;
import org.ow2.proactive.scheduler.common.exception.JobAlreadyFinishedException;
import org.ow2.proactive.scheduler.common.exception.JobCreationException;
import org.ow2.proactive.scheduler.common.exception.NotConnectedException;
import org.ow2.proactive.scheduler.common.exception.PermissionException;
import org.ow2.proactive.scheduler.common.exception.SubmissionClosedException;
import org.ow2.proactive.scheduler.common.exception.UnknownJobException;
import org.ow2.proactive.scheduler.common.exception.UnknownTaskException;
import org.ow2.proactive.scheduler.common.job.Job;
import org.ow2.proactive.scheduler.common.job.JobId;
import org.ow2.proactive.scheduler.common.job.JobInfo;
import org.ow2.proactive.scheduler.common.job.JobPriority;
import org.ow2.proactive.scheduler.common.job.JobResult;
import org.ow2.proactive.scheduler.common.job.JobState;
import org.ow2.proactive.scheduler.common.job.JobStatus;
import org.ow2.proactive.scheduler.common.job.TaskFlowJob;
import org.ow2.proactive.scheduler.common.job.factories.Job2XMLTransformer;
import org.ow2.proactive.scheduler.common.task.TaskId;
import org.ow2.proactive.scheduler.common.task.TaskResult;
import org.ow2.proactive.scheduler.common.task.TaskState;
import org.ow2.proactive.scheduler.common.usage.JobUsage;
import org.ow2.proactive.scheduler.job.JobIdImpl;
import org.ow2.proactive.scheduler.job.SchedulerUserInfo;
import org.ow2.proactive.scheduler.rest.data.DataUtility;
import org.ow2.proactive.scheduler.rest.data.JobInfoImpl;
import org.ow2.proactive.scheduler.rest.data.TaskResultImpl;
import org.ow2.proactive.scheduler.rest.data.TaskStateImpl;
import org.ow2.proactive.scheduler.rest.readers.OctetStreamReader;
import org.ow2.proactive.scheduler.rest.readers.TaskResultReader;
import org.ow2.proactive.scheduler.rest.readers.WildCardTypeReader;
import org.ow2.proactive.scheduler.task.TaskIdImpl;
import org.ow2.proactive_grid_cloud_portal.common.SchedulerRestInterface;
import org.ow2.proactive_grid_cloud_portal.common.dto.LoginForm;
import org.ow2.proactive_grid_cloud_portal.scheduler.client.SchedulerRestClient;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.JobIdData;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.JobInfoData;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.JobResultData;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.JobStateData;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.JobUsageData;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.RestPage;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.SchedulerStatusData;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.SchedulerUserData;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.TaskIdData;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.TaskInfoData;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.TaskResultData;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.TaskStateData;
import org.ow2.proactive_grid_cloud_portal.scheduler.dto.UserJobData;
import org.ow2.proactive_grid_cloud_portal.scheduler.exception.NotConnectedRestException;
import org.ow2.proactive_grid_cloud_portal.scheduler.exception.PermissionRestException;
import org.ow2.proactive_grid_cloud_portal.scheduler.exception.SchedulerRestException;
import org.ow2.proactive_grid_cloud_portal.scheduler.exception.UnknownJobRestException;
public class SchedulerClient extends ClientBase implements ISchedulerClient {
private static final long RETRY_INTERVAL = TimeUnit.SECONDS.toMillis(1);
private SchedulerRestClient schedulerRestClient;
private String sid;
private ConnectionInfo connectionInfo;
private boolean initialized = false;
private SchedulerEventReceiver schedulerEventReceiver;
private static final Logger logger = ProActiveLogger.getLogger(SchedulerClient.class);
private SchedulerClient() {
}
/**
* Creates an ISchedulerClient instance.
*
* @return an ISchedulerClient instance
*/
public static ISchedulerClient createInstance() {
SchedulerClient client = new SchedulerClient();
return (ISchedulerClient) Proxy.newProxyInstance(ISchedulerClient.class.getClassLoader(),
new Class[] { ISchedulerClient.class },
new SessionHandler(client));
}
@Override
public void init(ConnectionInfo connectionInfo) throws Exception {
HttpClient client = new HttpClientBuilder().insecure(connectionInfo.isInsecure()).useSystemProperties().build();
SchedulerRestClient restApiClient = new SchedulerRestClient(connectionInfo.getUrl(),
new ApacheHttpClient4Engine(client));
ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance();
factory.register(new WildCardTypeReader());
factory.register(new OctetStreamReader());
factory.register(new TaskResultReader());
setApiClient(restApiClient);
this.connectionInfo = connectionInfo;
this.initialized = true;
renewSession();
}
private void checkInitialized() {
if (!initialized) {
throw new IllegalStateException("SchedulerClient not initialized.");
}
}
@Override
public List<JobUsage> getAccountUsage(String user, Date start, Date end)
throws NotConnectedException, PermissionException {
List<JobUsage> jobUsages = null;
try {
List<JobUsageData> jobUsageDataList = restApi().getUsageOnAccount(sid, user, start, end);
jobUsages = toJobUsages(jobUsageDataList);
} catch (Exception e) {
throwNCEOrPE(e);
}
return jobUsages;
}
@Override
public List<JobUsage> getMyAccountUsage(Date startDate, Date endDate)
throws NotConnectedException, PermissionException {
List<JobUsage> jobUsages = null;
try {
List<JobUsageData> jobUsageDataList = restApi().getUsageOnMyAccount(sid, startDate, endDate);
jobUsages = toJobUsages(jobUsageDataList);
} catch (Exception e) {
throwNCEOrPE(e);
}
return jobUsages;
}
@Override
public void changeJobPriority(JobId jobId, JobPriority priority)
throws NotConnectedException, UnknownJobException, PermissionException, JobAlreadyFinishedException {
changeJobPriority(jobId.value(), priority);
}
@Override
public void changeJobPriority(String jobId, JobPriority priority)
throws NotConnectedException, UnknownJobException, PermissionException, JobAlreadyFinishedException {
try {
restApi().schedulerChangeJobPriorityByName(sid, jobId, priority.name());
} catch (Exception e) {
throwJAFEOrUJEOrNCEOrPE(e);
}
}
@Override
public void disconnect() throws NotConnectedException, PermissionException {
try {
restApi().disconnect(sid);
} catch (Exception e) {
throwNCEOrPE(e);
}
initialized = false;
}
@Override
public boolean freeze() throws NotConnectedException, PermissionException {
boolean success = false;
try {
success = restApi().freezeScheduler(sid);
} catch (Exception e) {
throwNCEOrPE(e);
}
return success;
}
@Override
public JobResult getJobResult(JobId jobId) throws NotConnectedException, PermissionException, UnknownJobException {
return getJobResult(jobId.value());
}
@Override
public JobResult getJobResult(String jobId) throws NotConnectedException, PermissionException, UnknownJobException {
JobResult jobResult = null;
try {
JobResultData jobResultData = restApi().jobResult(sid, jobId);
jobResult = toJobResult(jobResultData);
} catch (Exception e) {
throwUJEOrNCEOrPE(e);
}
return jobResult;
}
@Override
public JobState getJobState(String jobId) throws NotConnectedException, UnknownJobException, PermissionException {
JobState jobState = null;
try {
JobStateData jobStateData = restApi().listJobs(sid, jobId);
jobState = toJobState(jobStateData);
} catch (Exception e) {
throwUJEOrNCEOrPE(e);
}
return jobState;
}
@Override
public JobState getJobState(JobId jobId) throws NotConnectedException, UnknownJobException, PermissionException {
return getJobState(jobId.value());
}
@Override
public Page<JobInfo> getJobs(int index, int range, JobFilterCriteria criteria,
List<SortParameter<JobSortParameter>> arg3) throws NotConnectedException, PermissionException {
Page<JobInfo> jobInfos = null;
try {
RestPage<UserJobData> userJobDataList = restApi().jobsInfo(sid, index, range);
jobInfos = new Page<JobInfo>(toJobInfos(userJobDataList.getList()), userJobDataList.getSize());
} catch (Exception e) {
throwNCEOrPE(e);
}
return jobInfos;
}
@Override
public String getJobServerLogs(String jobId)
throws UnknownJobException, NotConnectedException, PermissionException {
String jobServerLog = "";
try {
jobServerLog = restApi().jobServerLog(sid, jobId);
} catch (Exception e) {
throwUJEOrNCEOrPE(e);
}
return jobServerLog;
}
@Override
public SchedulerStatus getStatus() throws NotConnectedException, PermissionException {
SchedulerStatus status = null;
try {
SchedulerStatusData schedulerStatus = restApi().getSchedulerStatus(sid);
status = SchedulerStatus.valueOf(schedulerStatus.name());
} catch (Exception e) {
throwNCEOrPE(e);
}
return status;
}
@Override
public TaskResult getTaskResult(String jobId, String taskName)
throws NotConnectedException, UnknownJobException, UnknownTaskException, PermissionException {
TaskResultImpl taskResult = null;
try {
TaskResultData taskResultData = restApi().taskResult(sid, jobId, taskName);
taskResult = (TaskResultImpl) toTaskResult(JobIdImpl.makeJobId(jobId), taskResultData);
if (taskResult.value() == null) {
Serializable value = restApi().valueOfTaskResult(sid, jobId, taskName);
if (value != null) {
taskResult.setValue(value);
}
}
} catch (Throwable t) {
throwUJEOrNCEOrPEOrUTE(exception(t));
}
return taskResult;
}
@Override
public TaskResult getTaskResult(JobId jobId, String taskName)
throws NotConnectedException, UnknownJobException, UnknownTaskException, PermissionException {
return getTaskResult(jobId.value(), taskName);
}
@Override
public List<TaskResult> getTaskResultsByTag(JobId jobId, String taskTag)
throws NotConnectedException, UnknownJobException, PermissionException {
List<TaskState> taskStates = getJobState(jobId).getTasksByTag(taskTag);
ArrayList<TaskResult> results = new ArrayList<TaskResult>(taskStates.size());
for (TaskState currentState : taskStates) {
String taskName = currentState.getTaskInfo().getName();
try {
TaskResult currentResult = getTaskResult(jobId, taskName);
results.add(currentResult);
} catch (UnknownTaskException ex) {
// never occurs because tasks are filtered by tag so they cannot
// be unknown.
logger.warn("Unknown task.", ex);
}
}
return results;
}
@Override
public List<TaskResult> getTaskResultsByTag(String jobId, String taskTag)
throws NotConnectedException, UnknownJobException, PermissionException {
return this.getTaskResultsByTag(JobIdImpl.makeJobId(jobId), taskTag);
}
@Override
public String getTaskServerLogs(String jobId, String taskName)
throws UnknownJobException, UnknownTaskException, NotConnectedException, PermissionException {
String taskLogs = "";
try {
taskLogs = restApi().taskLog(sid, jobId, taskName);
} catch (Exception e) {
throwUJEOrNCEOrPEOrUTE(e);
}
return taskLogs;
}
@Override
public String getTaskServerLogsByTag(String jobId, String tag)
throws UnknownJobException, NotConnectedException, PermissionException {
String taskLogs = "";
try {
taskLogs = restApi().taskLogByTag(sid, jobId, tag);
} catch (Exception e) {
throwUJEOrNCEOrPE(e);
}
return taskLogs;
}
@Override
public List<SchedulerUserInfo> getUsers() throws NotConnectedException, PermissionException {
List<SchedulerUserInfo> schedulerUserInfos = null;
try {
List<SchedulerUserData> users = restApi().getUsers(sid);
schedulerUserInfos = toSchedulerUserInfos(users);
} catch (Exception e) {
throwNCEOrPE(e);
}
return schedulerUserInfos;
}
@Override
public List<SchedulerUserInfo> getUsersWithJobs() throws NotConnectedException, PermissionException {
List<SchedulerUserInfo> schedulerUserInfos = null;
try {
List<SchedulerUserData> usersWithJobs = restApi().getUsersWithJobs(sid);
schedulerUserInfos = toSchedulerUserInfos(usersWithJobs);
} catch (Exception e) {
throwNCEOrPE(e);
}
return schedulerUserInfos;
}
@Override
public boolean isConnected() {
boolean isConnected = false;
if (initialized) {
try {
isConnected = restApi().isConnected(sid);
} catch (Throwable e) {
// ignore
}
}
return isConnected;
}
@Override
public boolean kill() throws NotConnectedException, PermissionException {
boolean isKilled = false;
try {
isKilled = restApi().killScheduler(sid);
} catch (Exception e) {
throwNCEOrPE(e);
}
return isKilled;
}
@Override
public boolean killJob(JobId jobId) throws NotConnectedException, UnknownJobException, PermissionException {
return killJob(jobId.value());
}
@Override
public boolean killJob(String jobId) throws NotConnectedException, UnknownJobException, PermissionException {
boolean isJobKilled = false;
try {
isJobKilled = restApi().killJob(sid, jobId);
} catch (Exception e) {
throwNCEOrPE(e);
}
return isJobKilled;
}
@Override
public boolean killTask(JobId jobId, String taskName)
throws NotConnectedException, UnknownJobException, PermissionException {
return killTask(jobId.value(), taskName);
}
@Override
public boolean killTask(String jobId, String taskName)
throws NotConnectedException, UnknownJobException, PermissionException {
boolean isTaskKilled = false;
try {
isTaskKilled = restApi().killTask(sid, jobId, taskName);
} catch (Exception e) {
throwNCEOrPE(e);
}
return isTaskKilled;
}
@Override
public boolean linkResourceManager(String rmUrl) throws NotConnectedException, PermissionException {
boolean isLinked = false;
try {
isLinked = restApi().linkRm(sid, rmUrl);
} catch (Exception e) {
throwNCEOrPE(e);
}
return isLinked;
}
@Override
public boolean pause() throws NotConnectedException, PermissionException {
boolean isSchedulerPaused = false;
try {
isSchedulerPaused = restApi().pauseScheduler(sid);
} catch (Exception e) {
throwNCEOrPE(e);
}
return isSchedulerPaused;
}
@Override
public boolean pauseJob(JobId jobId) throws NotConnectedException, UnknownJobException, PermissionException {
return pauseJob(jobId.value());
}
@Override
public boolean pauseJob(String jobId) throws NotConnectedException, UnknownJobException, PermissionException {
boolean isJobPaused = false;
try {
isJobPaused = restApi().pauseJob(sid, jobId);
} catch (Exception e) {
throwUJEOrNCEOrPE(e);
}
return isJobPaused;
}
@Override
public boolean restartAllInErrorTasks(String jobId)
throws NotConnectedException, UnknownJobException, PermissionException {
boolean isAllInErrorTasksRestarted = false;
try {
isAllInErrorTasksRestarted = restApi().restartAllInErrorTasks(sid, jobId);
} catch (Exception e) {
throwUJEOrNCEOrPE(e);
}
return isAllInErrorTasksRestarted;
}
@Override
public boolean preemptTask(JobId jobId, String taskName, int restartDelay)
throws NotConnectedException, UnknownJobException, UnknownTaskException, PermissionException {
return preemptTask(jobId.value(), taskName, restartDelay);
}
@Override
public boolean preemptTask(String jobId, String taskName, int restartDelay)
throws NotConnectedException, UnknownJobException, UnknownTaskException, PermissionException {
boolean isTaskPreempted = false;
try {
isTaskPreempted = restApi().preemptTask(sid, jobId, taskName);
} catch (Exception e) {
throwUJEOrNCEOrPEOrUTE(e);
}
return isTaskPreempted;
}
@Override
public boolean removeJob(JobId jobId) throws NotConnectedException, UnknownJobException, PermissionException {
return removeJob(jobId.value());
}
@Override
public boolean removeJob(String jobId) throws NotConnectedException, UnknownJobException, PermissionException {
boolean isJobRemoved = false;
try {
isJobRemoved = restApi().removeJob(sid, jobId);
} catch (Exception e) {
throwNCEOrPE(e);
}
return isJobRemoved;
}
@Override
public boolean restartTask(JobId jobId, String taskName, int restartDelay)
throws NotConnectedException, UnknownJobException, UnknownTaskException, PermissionException {
return restartTask(jobId.value(), taskName, restartDelay);
}
@Override
public boolean restartTask(String jobId, String taskName, int restartDelay)
throws NotConnectedException, UnknownJobException, UnknownTaskException, PermissionException {
boolean isTaskRestarted = false;
try {
isTaskRestarted = restApi().restartTask(sid, jobId, taskName);
} catch (Exception e) {
throwUJEOrNCEOrPEOrUTE(e);
}
return isTaskRestarted;
}
@Override
public boolean finishInErrorTask(String jobId, String taskName)
throws NotConnectedException, UnknownJobException, UnknownTaskException, PermissionException {
boolean result = false;
try {
result = restApi().finishInErrorTask(sid, jobId, taskName);
} catch (Exception e) {
throwUJEOrNCEOrPEOrUTE(e);
}
return result;
}
@Override
public boolean restartInErrorTask(String jobId, String taskName)
throws NotConnectedException, UnknownJobException, UnknownTaskException, PermissionException {
boolean result = false;
try {
result = restApi().restartInErrorTask(sid, jobId, taskName);
} catch (Exception e) {
throwUJEOrNCEOrPEOrUTE(e);
}
return result;
}
@Override
public boolean resume() throws NotConnectedException, PermissionException {
boolean isResumed = false;
try {
isResumed = restApi().resumeScheduler(sid);
} catch (Exception e) {
throwNCEOrPE(e);
}
return isResumed;
}
@Override
public boolean resumeJob(JobId jobId) throws NotConnectedException, UnknownJobException, PermissionException {
return resumeJob(jobId.value());
}
@Override
public boolean resumeJob(String jobId) throws NotConnectedException, UnknownJobException, PermissionException {
boolean isJobResumed = false;
try {
isJobResumed = restApi().resumeJob(sid, jobId);
} catch (Exception e) {
throwUJEOrNCEOrPE(e);
}
return isJobResumed;
}
@Override
public boolean shutdown() throws NotConnectedException, PermissionException {
boolean isShutdown = false;
try {
isShutdown = restApi().killScheduler(sid);
} catch (Exception e) {
throwNCEOrPE(e);
}
return isShutdown;
}
@Override
public boolean start() throws NotConnectedException, PermissionException {
boolean success = false;
try {
success = restApi().startScheduler(sid);
} catch (Exception e) {
throwNCEOrPE(e);
}
return success;
}
@Override
public boolean stop() throws NotConnectedException, PermissionException {
boolean isStopped = false;
try {
isStopped = restApi().stopScheduler(sid);
} catch (Exception e) {
throwNCEOrPE(e);
}
return isStopped;
}
@Override
public JobId submit(Job job)
throws NotConnectedException, PermissionException, SubmissionClosedException, JobCreationException {
JobIdData jobIdData = null;
try {
InputStream is = (new Job2XMLTransformer()).jobToxml((TaskFlowJob) job);
jobIdData = restApiClient().submitXml(sid, is);
} catch (Exception e) {
throwNCEOrPEOrSCEOrJCE(e);
}
return jobId(jobIdData);
}
@Override
public JobId submit(File job)
throws NotConnectedException, PermissionException, SubmissionClosedException, JobCreationException {
JobIdData jobIdData = null;
try {
InputStream is = new FileInputStream(job);
jobIdData = restApiClient().submitXml(sid, is);
} catch (Exception e) {
throwNCEOrPEOrSCEOrJCE(e);
}
return jobId(jobIdData);
}
@Override
public JobId submit(URL job)
throws NotConnectedException, PermissionException, SubmissionClosedException, JobCreationException {
JobIdData jobIdData = null;
try {
InputStream is = job.openStream();
jobIdData = restApiClient().submitXml(sid, is);
} catch (Exception e) {
throwNCEOrPEOrSCEOrJCE(e);
}
return jobId(jobIdData);
}
@Override
public JobId submit(File job, Map<String, String> variables)
throws NotConnectedException, PermissionException, SubmissionClosedException, JobCreationException {
JobIdData jobIdData = null;
try {
InputStream is = new FileInputStream(job);
jobIdData = restApiClient().submitXml(sid, is, variables);
} catch (Exception e) {
throwNCEOrPEOrSCEOrJCE(e);
}
return jobId(jobIdData);
}
@Override
public JobId submit(URL job, Map<String, String> variables)
throws NotConnectedException, PermissionException, SubmissionClosedException, JobCreationException {
JobIdData jobIdData = null;
try {
InputStream is = job.openStream();
jobIdData = restApiClient().submitXml(sid, is, variables);
} catch (Exception e) {
throwNCEOrPEOrSCEOrJCE(e);
}
return jobId(jobIdData);
}
@Override
public boolean isJobFinished(JobId jobId) throws NotConnectedException, UnknownJobException, PermissionException {
return isJobFinished(jobId.toString());
}
@Override
public boolean isJobFinished(String jobId) throws NotConnectedException, UnknownJobException, PermissionException {
return !getJobState(jobId).getStatus().isJobAlive();
}
@Override
public JobResult waitForJob(JobId jobId, long timeout)
throws NotConnectedException, UnknownJobException, PermissionException, TimeoutException {
return waitForJob(jobId.value(), timeout);
}
@Override
public JobResult waitForJob(String jobId, long timeout)
throws NotConnectedException, UnknownJobException, PermissionException, TimeoutException {
timeout += currentTimeMillis();
while (currentTimeMillis() < timeout) {
if (isJobFinished(jobId)) {
return getJobResult(jobId);
}
if (currentTimeMillis() + RETRY_INTERVAL < timeout) {
sleep(RETRY_INTERVAL);
} else {
break;
}
}
throw new TimeoutException(format("Timeout waiting for the job: job-id=%s", jobId));
}
@Override
public boolean isTaskFinished(String jobId, String taskName)
throws UnknownJobException, NotConnectedException, PermissionException, UnknownTaskException {
boolean finished = false;
try {
TaskStateData taskStateData = restApi().jobTask(sid, jobId, taskName);
TaskState taskState = taskState(taskStateData);
finished = !taskState.getStatus().isTaskAlive();
} catch (Exception e) {
throwUJEOrNCEOrPEOrUTE(e);
}
return finished;
}
@Override
public TaskResult waitForTask(String jobId, String taskName, long timeout) throws UnknownJobException,
NotConnectedException, PermissionException, UnknownTaskException, TimeoutException {
timeout += currentTimeMillis();
while (currentTimeMillis() < timeout) {
if (isTaskFinished(jobId, taskName)) {
return getTaskResult(jobId, taskName);
}
if (currentTimeMillis() + RETRY_INTERVAL < timeout) {
sleep(RETRY_INTERVAL);
} else {
break;
}
}
throw new TimeoutException(format("Timeout waiting for the task: job-id=%s, task-id=%s", jobId, taskName));
}
@Override
public List<JobResult> waitForAllJobs(List<String> jobIds, long timeout)
throws NotConnectedException, UnknownJobException, PermissionException, TimeoutException {
long timestamp = 0;
List<JobResult> results = new ArrayList<>(jobIds.size());
for (String jobId : jobIds) {
timestamp = currentTimeMillis();
results.add(waitForJob(jobId, timeout));
timeout = timeout - (currentTimeMillis() - timestamp);
}
return results;
}
@Override
public Map.Entry<String, JobResult> waitForAnyJob(List<String> jobIds, long timeout)
throws NotConnectedException, UnknownJobException, PermissionException, TimeoutException {
timeout += currentTimeMillis();
while (currentTimeMillis() < timeout) {
for (String jobId : jobIds) {
if (isJobFinished(jobId)) {
return toEntry(jobId, getJobResult(jobId));
}
}
if (currentTimeMillis() + RETRY_INTERVAL < timeout) {
sleep(RETRY_INTERVAL);
} else {
break;
}
}
throw new TimeoutException(format("Timeout waiting for any job: jobIds=%s.", String.valueOf(jobIds)));
}
@Override
public Entry<String, TaskResult> waitForAnyTask(String jobId, List<String> taskNames, long timeout)
throws UnknownJobException, NotConnectedException, PermissionException, UnknownTaskException,
TimeoutException {
timeout += currentTimeMillis();
while (currentTimeMillis() < timeout) {
for (String taskName : taskNames) {
if (isTaskFinished(jobId, taskName)) {
return toEntry(taskName, getTaskResult(jobId, taskName));
}
}
if (currentTimeMillis() + RETRY_INTERVAL < timeout) {
sleep(RETRY_INTERVAL);
} else {
break;
}
}
throw new TimeoutException(format("Timeout waiting for any task: job-id=%s, task-ids=%s.",
jobId,
String.valueOf(taskNames)));
}
@Override
public List<Entry<String, TaskResult>> waitForAllTasks(String jobId, List<String> taskNames, long timeout)
throws UnknownJobException, NotConnectedException, PermissionException, UnknownTaskException,
TimeoutException {
long timestamp = 0;
List<Map.Entry<String, TaskResult>> taskResults = new ArrayList<>(taskNames.size());
for (String taskName : taskNames) {
timestamp = currentTimeMillis();
Entry<String, TaskResult> taskResultEntry = toEntry(taskName, waitForTask(jobId, taskName, timeout));
taskResults.add(taskResultEntry);
timeout = timeout - (currentTimeMillis() - timestamp);
}
return taskResults;
}
@Override
public boolean pushFile(String spacename, String pathname, String filename, String file)
throws NotConnectedException, PermissionException {
boolean uploaded = false;
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
uploaded = restApiClient().pushFile(sid, spacename, pathname, filename, inputStream);
} catch (Exception e) {
throwNCEOrPE(e);
} finally {
closeIfPossible(inputStream);
}
return uploaded;
}
@Override
public void pullFile(String space, String pathname, String outputFile)
throws NotConnectedException, PermissionException {
try {
restApiClient().pullFile(sid, space, pathname, outputFile);
} catch (Exception e) {
throwNCEOrPE(e);
}
}
@Override
public boolean deleteFile(String space, String pathname) throws NotConnectedException, PermissionException {
boolean deleted = false;
try {
deleted = restApi().deleteFile(sid, space, pathname);
} catch (Exception e) {
throwNCEOrPE(e);
}
return deleted;
}
@Override
public List<String> getUserSpaceURIs() throws NotConnectedException, PermissionException {
try {
return restApi().userspaceURIs(sid);
} catch (Exception error) {
throw throwNCEOrPE(error);
}
}
@Override
public List<String> getGlobalSpaceURIs() throws NotConnectedException, PermissionException {
try {
return restApi().globalspaceURIs(sid);
} catch (Exception error) {
throw throwNCEOrPE(error);
}
}
@Override
public void renewSession() throws NotConnectedException {
try {
LoginForm loginForm = new LoginForm();
loginForm.setUsername(connectionInfo.getLogin());
loginForm.setPassword(connectionInfo.getPassword());
if (connectionInfo.getCredentialFile() != null) {
loginForm.setCredential(new FileInputStream(connectionInfo.getCredentialFile()));
}
sid = restApi().loginOrRenewSession(sid, loginForm);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void setSession(String sid) {
this.sid = sid;
}
@Override
public String getSession() {
return sid;
}
@Override
public void addEventListener(SchedulerEventListener listener, boolean myEventsOnly, SchedulerEvent... events)
throws NotConnectedException, PermissionException {
try {
removeEventListener();
schedulerEventReceiver = (new SchedulerEventReceiver.Builder()).restServerUrl(connectionInfo.getUrl())
.sessionId(sid)
.schedulerEventListener(listener)
.myEventsOnly(myEventsOnly)
.selectedEvents(events)
.build();
schedulerEventReceiver.start();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void removeEventListener() throws NotConnectedException, PermissionException {
if (schedulerEventReceiver != null) {
schedulerEventReceiver.stop();
}
}
private void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException ie) {
// ignore
}
}
private void closeIfPossible(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ioe) {
// ignore
}
}
}
private SchedulerRestInterface restApi() {
checkInitialized();
return schedulerRestClient.getScheduler();
}
private void setApiClient(SchedulerRestClient schedulerRestClient) {
this.schedulerRestClient = schedulerRestClient;
}
private SchedulerRestClient restApiClient() {
return schedulerRestClient;
}
private <K, V> Map.Entry<K, V> toEntry(final K k, final V v) {
return new AbstractMap.SimpleEntry<>(k, v);
}
@Override
public void putThirdPartyCredential(String key, String value)
throws NotConnectedException, PermissionException, KeyException {
try {
restApi().putThirdPartyCredential(sid, key, value);
} catch (NotConnectedRestException e) {
throw new NotConnectedException(e);
} catch (PermissionRestException e) {
throw new PermissionException(e);
} catch (SchedulerRestException e) {
throw new KeyException(e);
}
}
@Override
public Set<String> thirdPartyCredentialsKeySet() throws NotConnectedException, PermissionException {
try {
return restApi().thirdPartyCredentialsKeySet(sid);
} catch (NotConnectedRestException e) {
throw new NotConnectedException(e);
} catch (PermissionRestException e) {
throw new PermissionException(e);
}
}
@Override
public void removeThirdPartyCredential(String key) throws NotConnectedException, PermissionException {
try {
restApi().removeThirdPartyCredential(sid, key);
} catch (NotConnectedRestException e) {
throw new NotConnectedException(e);
} catch (PermissionRestException e) {
throw new PermissionException(e);
}
}
@Override
public Page<TaskId> getTaskIds(String taskTag, long from, long to, boolean mytasks, boolean running,
boolean pending, boolean finished, int offset, int limit)
throws NotConnectedException, PermissionException {
RestPage<TaskStateData> page = null;
try {
page = restApi().getTaskStates(sid, from, to, mytasks, running, pending, finished, offset, limit, null);
} catch (NotConnectedRestException e) {
throw new NotConnectedException(e);
} catch (PermissionRestException e) {
throw new PermissionException(e);
}
List<TaskId> lTaskIds = new ArrayList<TaskId>(page.getList().size());
for (TaskStateData taskStateData : page.getList()) {
TaskInfoData taskInfo = taskStateData.getTaskInfo();
TaskIdData taskIdData = taskInfo.getTaskId();
JobId jobId = new JobIdImpl(taskInfo.getJobId().getId(), taskInfo.getJobId().getReadableName());
TaskId taskId = TaskIdImpl.createTaskId(jobId, taskIdData.getReadableName(), taskIdData.getId());
lTaskIds.add(taskId);
}
return new Page<TaskId>(lTaskIds, page.getSize());
}
@Override
public Page<TaskState> getTaskStates(String taskTag, long from, long to, boolean mytasks, boolean running,
boolean pending, boolean finished, int offset, int limit, SortSpecifierContainer sortParams)
throws NotConnectedException, PermissionException {
RestPage<TaskStateData> page = null;
SortSpecifierContainer sortContainer = new SortSpecifierContainer(sortParams.toString());
try {
page = restApi().getTaskStates(sid,
from,
to,
mytasks,
running,
pending,
finished,
offset,
limit,
sortContainer);
} catch (NotConnectedRestException e) {
throw new NotConnectedException(e);
} catch (PermissionRestException e) {
throw new PermissionException(e);
}
List<TaskState> lTaskStates = new ArrayList<TaskState>(page.getList().size());
for (TaskStateData taskStateData : page.getList()) {
lTaskStates.add(new TaskStateImpl(taskStateData));
}
return new Page<TaskState>(lTaskStates, page.getSize());
}
@Override
public JobInfo getJobInfo(String jobId) throws UnknownJobException, NotConnectedException, PermissionException {
JobInfoData jobInfoData = null;
try {
jobInfoData = restApi().jobInfo(sid, jobId);
} catch (NotConnectedRestException e) {
throw new NotConnectedException(e);
} catch (PermissionRestException e) {
throw new PermissionException(e);
} catch (UnknownJobRestException e) {
throw new UnknownJobException(e);
}
JobInfoImpl jobInfoImpl = new JobInfoImpl();
JobId newJobId = JobIdImpl.makeJobId(jobId);
jobInfoImpl.setJobId(newJobId);
jobInfoImpl.setJobOwner(jobInfoData.getJobOwner());
jobInfoImpl.setFinishedTime(jobInfoData.getFinishedTime());
jobInfoImpl.setRemovedTime(jobInfoData.getRemovedTime());
jobInfoImpl.setStartTime(jobInfoData.getStartTime());
jobInfoImpl.setInErrorTime(jobInfoData.getInErrorTime());
jobInfoImpl.setSubmittedTime(jobInfoData.getSubmittedTime());
jobInfoImpl.setNumberOfFinishedTasks(jobInfoData.getNumberOfFinishedTasks());
jobInfoImpl.setNumberOfPendingTasks(jobInfoData.getNumberOfPendingTasks());
jobInfoImpl.setNumberOfRunningTasks(jobInfoData.getNumberOfRunningTasks());
jobInfoImpl.setNumberOfInErrorTasks(jobInfoData.getNumberOfInErrorTasks());
jobInfoImpl.setNumberOfFaultyTasks(jobInfoData.getNumberOfFaultyTasks());
jobInfoImpl.setTotalNumberOfTasks(jobInfoData.getTotalNumberOfTasks());
jobInfoImpl.setJobPriority(JobPriority.findPriority(jobInfoData.getPriority().toString()));
jobInfoImpl.setJobStatus(JobStatus.findPriority(jobInfoData.getStatus().toString()));
if (jobInfoData.isToBeRemoved())
jobInfoImpl.setToBeRemoved();
jobInfoImpl.setGenericInformation(jobInfoData.getGenericInformation());
jobInfoImpl.setVariables(jobInfoData.getVariables());
return jobInfoImpl;
}
@Override
public boolean changeStartAt(JobId jobId, String startAt)
throws NotConnectedException, UnknownJobException, PermissionException {
boolean isJobStartAtChanged = false;
try {
isJobStartAtChanged = restApi().changeStartAt(sid, jobId.value(), startAt);
} catch (Exception e) {
throwUJEOrNCEOrPE(e);
}
return isJobStartAtChanged;
}
@Override
public JobId copyJobAndResubmitWithGeneralInfo(JobId jobId, Map<String, String> generalInfo)
throws NotConnectedException, UnknownJobException, PermissionException, SubmissionClosedException,
JobCreationException {
try {
JobIdData id = restApi().copyAndResubmitWithGeneralInfo(sid, jobId.value(), generalInfo);
return id == null ? null : DataUtility.jobId(id);
} catch (Exception e) {
throwNCEOrPEOrSCEOrJCE(e);
}
return null;
}
@Override
public Map<Object, Object> getPortalConfiguration() throws NotConnectedException, PermissionException {
try {
return restApi().getPortalConfiguration(sid);
} catch (NotConnectedRestException e) {
throw new NotConnectedException(e);
} catch (PermissionRestException e) {
throw new PermissionException(e);
}
}
@Override
public String getCurrentUser() throws NotConnectedException {
String connectedUser = restApi().getLoginFromSessionId(sid);
if ("".equals(connectedUser)) {
throw new NotConnectedException("Session " + sid + " is not connected");
}
return connectedUser;
}
}