use of com.netflix.conductor.core.execution.ApplicationException in project conductor by Netflix.
the class TestSimpleEventProcessor method testEventProcessorWithRetriableError.
@Test
public void testEventProcessorWithRetriableError() {
EventHandler eventHandler = new EventHandler();
eventHandler.setName(UUID.randomUUID().toString());
eventHandler.setActive(true);
eventHandler.setEvent(event);
Action completeTaskAction = new Action();
completeTaskAction.setAction(Type.complete_task);
completeTaskAction.setComplete_task(new TaskDetails());
completeTaskAction.getComplete_task().setTaskRefName("task_x");
completeTaskAction.getComplete_task().setWorkflowId(UUID.randomUUID().toString());
completeTaskAction.getComplete_task().setOutput(new HashMap<>());
eventHandler.getActions().add(completeTaskAction);
when(queue.rePublishIfNoAck()).thenReturn(false);
when(metadataService.getAllEventHandlers()).thenReturn(Collections.singletonList(eventHandler));
when(metadataService.getEventHandlersForEvent(event, true)).thenReturn(Collections.singletonList(eventHandler));
when(executionService.addEventExecution(any())).thenReturn(true);
when(actionProcessor.execute(any(), any(), any(), any())).thenThrow(new ApplicationException(ApplicationException.Code.BACKEND_ERROR, "some retriable error"));
SimpleEventProcessor eventProcessor = new SimpleEventProcessor(executionService, metadataService, actionProcessor, eventQueues, jsonUtils, new TestConfiguration(), objectMapper);
assertNotNull(eventProcessor.getQueues());
assertEquals(1, eventProcessor.getQueues().size());
Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
verify(queue, never()).ack(any());
verify(queue, never()).publish(any());
}
use of com.netflix.conductor.core.execution.ApplicationException in project conductor by Netflix.
the class ExecutionDAOFacade method getWorkflowById.
/**
* Fetches the {@link Workflow} object from the data store given the id.
* Attempts to fetch from {@link ExecutionDAO} first,
* if not found, attempts to fetch from {@link IndexDAO}.
*
* @param workflowId the id of the workflow to be fetched
* @param includeTasks if true, fetches the {@link Task} data in the workflow.
* @return the {@link Workflow} object
* @throws ApplicationException if
* <ul>
* <li>no such {@link Workflow} is found</li>
* <li>parsing the {@link Workflow} object fails</li>
* </ul>
*/
public Workflow getWorkflowById(String workflowId, boolean includeTasks) {
Workflow workflow = executionDAO.getWorkflow(workflowId, includeTasks);
if (workflow == null) {
LOGGER.debug("Workflow {} not found in executionDAO, checking indexDAO", workflowId);
String json = indexDAO.get(workflowId, RAW_JSON_FIELD);
if (json == null) {
String errorMsg = String.format("No such workflow found by id: %s", workflowId);
LOGGER.error(errorMsg);
throw new ApplicationException(ApplicationException.Code.NOT_FOUND, errorMsg);
}
try {
workflow = objectMapper.readValue(json, Workflow.class);
if (!includeTasks) {
workflow.getTasks().clear();
}
} catch (IOException e) {
String errorMsg = String.format("Error reading workflow: %s", workflowId);
LOGGER.error(errorMsg);
throw new ApplicationException(ApplicationException.Code.BACKEND_ERROR, errorMsg, e);
}
}
return workflow;
}
use of com.netflix.conductor.core.execution.ApplicationException in project conductor by Netflix.
the class ExecutionDAOFacade method removeWorkflowWithExpiry.
public void removeWorkflowWithExpiry(String workflowId, boolean archiveWorkflow, int ttlSeconds) {
try {
Workflow workflow = getWorkflowById(workflowId, true);
removeWorkflowIndex(workflow, archiveWorkflow);
// remove workflow from DAO with TTL
try {
executionDAO.removeWorkflowWithExpiry(workflowId, ttlSeconds);
} catch (Exception ex) {
Monitors.recordDaoError("executionDao", "removeWorkflow");
throw ex;
}
} catch (ApplicationException ae) {
throw ae;
} catch (Exception e) {
throw new ApplicationException(ApplicationException.Code.BACKEND_ERROR, "Error removing workflow: " + workflowId, e);
}
}
use of com.netflix.conductor.core.execution.ApplicationException in project conductor by Netflix.
the class ExecutionService method poll.
public List<Task> poll(String taskType, String workerId, String domain, int count, int timeoutInMilliSecond) {
if (timeoutInMilliSecond > MAX_POLL_TIMEOUT_MS) {
throw new ApplicationException(ApplicationException.Code.INVALID_INPUT, "Long Poll Timeout value cannot be more than 5 seconds");
}
String queueName = QueueUtils.getQueueName(taskType, domain, null, null);
List<String> taskIds = new LinkedList<>();
List<Task> tasks = new LinkedList<>();
try {
taskIds = queueDAO.pop(queueName, count, timeoutInMilliSecond);
} catch (Exception e) {
logger.error("Error polling for task: {} from worker: {} in domain: {}, count: {}", taskType, workerId, domain, count, e);
Monitors.error(this.getClass().getCanonicalName(), "taskPoll");
Monitors.recordTaskPollError(taskType, domain, e.getClass().getSimpleName());
}
for (String taskId : taskIds) {
try {
Task task = getTask(taskId);
if (task == null || task.getStatus().isTerminal()) {
// Remove taskId(s) without a valid Task/terminal state task from the queue
queueDAO.remove(queueName, taskId);
logger.debug("Removed task: {} from the queue: {}", taskId, queueName);
continue;
}
if (executionDAOFacade.exceedsInProgressLimit(task)) {
// Postpone this message, so that it would be available for poll again.
queueDAO.postpone(queueName, taskId, task.getWorkflowPriority(), queueTaskMessagePostponeSeconds);
logger.debug("Postponed task: {} in queue: {} by {} seconds", taskId, queueName, queueTaskMessagePostponeSeconds);
continue;
}
TaskDef taskDef = task.getTaskDefinition().isPresent() ? task.getTaskDefinition().get() : null;
if (task.getRateLimitPerFrequency() > 0 && executionDAOFacade.exceedsRateLimitPerFrequency(task, taskDef)) {
// Postpone this message, so that it would be available for poll again.
queueDAO.postpone(queueName, taskId, task.getWorkflowPriority(), queueTaskMessagePostponeSeconds);
logger.debug("RateLimit Execution limited for {}:{}, limit:{}", taskId, task.getTaskDefName(), task.getRateLimitPerFrequency());
continue;
}
task.setStatus(Status.IN_PROGRESS);
if (task.getStartTime() == 0) {
task.setStartTime(System.currentTimeMillis());
Monitors.recordQueueWaitTime(task.getTaskDefName(), task.getQueueWaitTime());
}
// reset callbackAfterSeconds when giving the task to the worker
task.setCallbackAfterSeconds(0);
task.setWorkerId(workerId);
task.setPollCount(task.getPollCount() + 1);
executionDAOFacade.updateTask(task);
tasks.add(task);
} catch (Exception e) {
// db operation failed for dequeued message, re-enqueue with a delay
logger.warn("DB operation failed for task: {}, postponing task in queue", taskId, e);
Monitors.recordTaskPollError(taskType, domain, e.getClass().getSimpleName());
queueDAO.postpone(queueName, taskId, 0, queueTaskMessagePostponeSeconds);
}
}
executionDAOFacade.updateTaskLastPoll(taskType, domain, workerId);
Monitors.recordTaskPoll(queueName);
return tasks;
}
use of com.netflix.conductor.core.execution.ApplicationException in project conductor by Netflix.
the class S3PayloadStorage method getLocation.
/**
* @param operation the type of {@link Operation} to be performed
* @param payloadType the {@link PayloadType} that is being accessed
* @return a {@link ExternalStorageLocation} object which contains the pre-signed URL and the s3 object key for the json payload
*/
@Override
public ExternalStorageLocation getLocation(Operation operation, PayloadType payloadType, String path) {
try {
ExternalStorageLocation externalStorageLocation = new ExternalStorageLocation();
Date expiration = new Date();
long expTimeMillis = expiration.getTime() + 1000 * expirationSec;
expiration.setTime(expTimeMillis);
HttpMethod httpMethod = HttpMethod.GET;
if (operation == Operation.WRITE) {
httpMethod = HttpMethod.PUT;
}
String objectKey;
if (StringUtils.isNotBlank(path)) {
objectKey = path;
} else {
objectKey = getObjectKey(payloadType);
}
externalStorageLocation.setPath(objectKey);
GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectKey).withMethod(httpMethod).withExpiration(expiration);
externalStorageLocation.setUri(s3Client.generatePresignedUrl(generatePresignedUrlRequest).toURI().toASCIIString());
return externalStorageLocation;
} catch (SdkClientException e) {
String msg = "Error communicating with S3";
logger.error(msg, e);
throw new ApplicationException(ApplicationException.Code.BACKEND_ERROR, msg, e);
} catch (URISyntaxException e) {
String msg = "Invalid URI Syntax";
logger.error(msg, e);
throw new ApplicationException(ApplicationException.Code.INTERNAL_ERROR, msg, e);
}
}
Aggregations