/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.vipr.client.core.impl; import java.util.ArrayList; import java.util.List; import com.emc.storageos.model.RestLinkRep; import com.emc.storageos.model.TaskResourceRep; import com.emc.storageos.model.errorhandling.ServiceErrorRestRep; import com.emc.vipr.client.AuthClient; import com.emc.vipr.client.exceptions.ServiceErrorException; import com.emc.vipr.client.exceptions.ServiceErrorsException; import com.emc.vipr.client.exceptions.TimeoutException; import com.emc.vipr.client.exceptions.ViPRException; import com.emc.vipr.client.impl.RestClient; public class TaskUtil { public enum State { queued, pending, error, suspended_no_error, suspended_error } public static TaskResourceRep refresh(RestClient client, TaskResourceRep task) { RestLinkRep link = task.getLink(); if (link == null) { throw new ViPRException("Task has no link"); } return client.get(TaskResourceRep.class, link.getLinkRef().toString()); } public static TaskResourceRep waitForTask(RestClient client, TaskResourceRep task, long timeoutMillis) { long startTime = System.currentTimeMillis(); while (isRunning(task) || isSuspended(task)) { if (timeoutMillis > 0 && (System.currentTimeMillis() - startTime) > timeoutMillis) { throw new TimeoutException("Timed out waiting for task to complete"); } try { Thread.sleep(client.getConfig().getTaskPollingInterval()); } catch (InterruptedException e) { throw new ViPRException(e); } refreshSession(client); task = refresh(client, task); } return task; } public static List<TaskResourceRep> waitForTasks(RestClient client, List<TaskResourceRep> tasks, long timeoutMillis) { List<TaskResourceRep> newTasks = new ArrayList<TaskResourceRep>(); for (TaskResourceRep task : tasks) { newTasks.add(waitForTask(client, task, timeoutMillis)); } return newTasks; } public static boolean isRunning(TaskResourceRep task) { return State.pending.name().equalsIgnoreCase(task.getState()) || State.queued.name().equalsIgnoreCase(task.getState()); } public static boolean isSuspended(TaskResourceRep task) { return State.suspended_no_error.name().equalsIgnoreCase(task.getState()) || State.suspended_error.name().equalsIgnoreCase(task.getState()); } public static boolean isQueued(TaskResourceRep task) { return State.queued.name().equalsIgnoreCase(task.getState()); } public static boolean isComplete(TaskResourceRep task) { return !isRunning(task) && !isSuspended(task); } public static boolean isError(TaskResourceRep task) { return task == null || task.getState() == null || State.error.name().equalsIgnoreCase(task.getState()); } /** * Checks a task state to see if it is in error. If it is, throws an * exception. * * @param task Task to check for errors on */ public static void checkForError(TaskResourceRep task) { if (isError(task)) { throw new ServiceErrorException(taskToError(task)); } } public static void checkForErrors(List<TaskResourceRep> tasks) { List<ServiceErrorRestRep> errors = new ArrayList<ServiceErrorRestRep>(); for (TaskResourceRep task : tasks) { if (task != null && isError(task)) { errors.add(taskToError(task)); } } if (errors.size() == 1) { throw new ServiceErrorException(errors.get(0)); } else if (errors.size() > 1) { throw new ServiceErrorsException(errors); } } private static ServiceErrorRestRep taskToError(TaskResourceRep task) { ServiceErrorRestRep serviceError = task.getServiceError(); if (task.getState() == null) { serviceError = new ServiceErrorRestRep(); serviceError.setCodeDescription("Task state is null. Unable to determine success of task"); serviceError.setDetailedMessage(""); } else if (serviceError == null) { serviceError = new ServiceErrorRestRep(); serviceError.setCodeDescription(task.getMessage() == null ? "No Message" : task.getMessage()); serviceError.setDetailedMessage(""); } return serviceError; } private synchronized static void refreshSession(RestClient client) { if (client.getLoginTime() > 0 && (System.currentTimeMillis() - client.getLoginTime()) > client.getConfig().getSessionKeyRenewTimeout() && client.getUsername() != null && client.getPassword() != null) { AuthClient authClient = new AuthClient(client); authClient.logout(); authClient.login(client.getUsername(), client.getPassword()); client.setProxyToken(authClient.proxyToken()); } } }