Search in sources :

Example 1 with ConductorClientException

use of com.netflix.conductor.client.exceptions.ConductorClientException in project conductor by Netflix.

the class ClientBase method downloadFromExternalStorage.

/**
 * Uses the {@link PayloadStorage} for downloading large payloads to be used by the client.
 * Gets the uri of the payload fom the server and then downloads from this location.
 *
 * @param payloadType the {@link com.netflix.conductor.common.utils.ExternalPayloadStorage.PayloadType} to be downloaded
 * @param path        the relative of the payload in external storage
 * @return the payload object that is stored in external storage
 */
@SuppressWarnings("unchecked")
protected Map<String, Object> downloadFromExternalStorage(ExternalPayloadStorage.PayloadType payloadType, String path) {
    Preconditions.checkArgument(StringUtils.isNotBlank(path), "uri cannot be blank");
    ExternalStorageLocation externalStorageLocation = payloadStorage.getLocation(ExternalPayloadStorage.Operation.READ, payloadType, path);
    try (InputStream inputStream = payloadStorage.download(externalStorageLocation.getUri())) {
        return objectMapper.readValue(inputStream, Map.class);
    } catch (IOException e) {
        String errorMsg = String.format("Unable to download payload from external storage location: %s", path);
        logger.error(errorMsg, e);
        throw new ConductorClientException(errorMsg, e);
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) ConductorClientException(com.netflix.conductor.client.exceptions.ConductorClientException) ExternalStorageLocation(com.netflix.conductor.common.run.ExternalStorageLocation)

Example 2 with ConductorClientException

use of com.netflix.conductor.client.exceptions.ConductorClientException in project conductor by Netflix.

the class PayloadStorage method upload.

/**
 * Uploads the payload to the uri specified.
 *
 * @param uri         the location to which the object is to be uploaded
 * @param payload     an {@link InputStream} containing the json payload which is to be uploaded
 * @param payloadSize the size of the json payload in bytes
 * @throws ConductorClientException if the upload fails due to an invalid path or an error from external storage
 */
@Override
public void upload(String uri, InputStream payload, long payloadSize) {
    HttpURLConnection connection = null;
    try {
        URL url = new URI(uri).toURL();
        connection = (HttpURLConnection) url.openConnection();
        connection.setDoOutput(true);
        connection.setRequestMethod("PUT");
        try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(connection.getOutputStream())) {
            long count = IOUtils.copy(payload, bufferedOutputStream);
            bufferedOutputStream.flush();
            // Check the HTTP response code
            int responseCode = connection.getResponseCode();
            if (Response.Status.fromStatusCode(responseCode).getFamily() != Response.Status.Family.SUCCESSFUL) {
                String errorMsg = String.format("Unable to upload. Response code: %d", responseCode);
                logger.error(errorMsg);
                throw new ConductorClientException(errorMsg);
            }
            logger.debug("Uploaded {} bytes to uri: {}, with HTTP response code: {}", count, uri, responseCode);
        }
    } catch (URISyntaxException | MalformedURLException e) {
        String errorMsg = String.format("Invalid path specified: %s", uri);
        logger.error(errorMsg, e);
        throw new ConductorClientException(errorMsg, e);
    } catch (IOException e) {
        String errorMsg = String.format("Error uploading to path: %s", uri);
        logger.error(errorMsg, e);
        throw new ConductorClientException(errorMsg, e);
    } finally {
        if (connection != null) {
            connection.disconnect();
        }
        try {
            if (payload != null) {
                payload.close();
            }
        } catch (IOException e) {
            logger.warn("Unable to close inputstream when uploading to uri: {}", uri);
        }
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) HttpURLConnection(java.net.HttpURLConnection) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) ConductorClientException(com.netflix.conductor.client.exceptions.ConductorClientException) URI(java.net.URI) BufferedOutputStream(java.io.BufferedOutputStream) URL(java.net.URL)

Example 3 with ConductorClientException

use of com.netflix.conductor.client.exceptions.ConductorClientException in project conductor by Netflix.

the class WorkflowClient method startWorkflow.

/**
 * Starts a workflow.
 * If the size of the workflow input payload is bigger than {@link ConductorClientConfiguration#getWorkflowInputPayloadThresholdKB()},
 * it is uploaded to {@link ExternalPayloadStorage}, if enabled, else the workflow is rejected.
 *
 * @param startWorkflowRequest the {@link StartWorkflowRequest} object to start the workflow
 * @return the id of the workflow instance that can be used for tracking
 * @throws ConductorClientException if {@link ExternalPayloadStorage} is disabled or if the payload size is greater than {@link ConductorClientConfiguration#getWorkflowInputMaxPayloadThresholdKB()}
 */
public String startWorkflow(StartWorkflowRequest startWorkflowRequest) {
    Preconditions.checkNotNull(startWorkflowRequest, "StartWorkflowRequest cannot be null");
    Preconditions.checkArgument(StringUtils.isNotBlank(startWorkflowRequest.getName()), "Workflow name cannot be null or empty");
    Preconditions.checkArgument(StringUtils.isBlank(startWorkflowRequest.getExternalInputPayloadStoragePath()), "External Storage Path must not be set");
    String version = startWorkflowRequest.getVersion() != null ? startWorkflowRequest.getVersion().toString() : "latest";
    try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
        objectMapper.writeValue(byteArrayOutputStream, startWorkflowRequest.getInput());
        byte[] workflowInputBytes = byteArrayOutputStream.toByteArray();
        long workflowInputSize = workflowInputBytes.length;
        MetricsContainer.recordWorkflowInputPayloadSize(startWorkflowRequest.getName(), version, workflowInputSize);
        if (workflowInputSize > conductorClientConfiguration.getWorkflowInputPayloadThresholdKB() * 1024) {
            if (!conductorClientConfiguration.isExternalPayloadStorageEnabled() || (workflowInputSize > conductorClientConfiguration.getWorkflowInputMaxPayloadThresholdKB() * 1024)) {
                String errorMsg = String.format("Input payload larger than the allowed threshold of: %d KB", conductorClientConfiguration.getWorkflowInputPayloadThresholdKB());
                throw new ConductorClientException(errorMsg);
            } else {
                MetricsContainer.incrementExternalPayloadUsedCount(startWorkflowRequest.getName(), ExternalPayloadStorage.Operation.WRITE.name(), ExternalPayloadStorage.PayloadType.WORKFLOW_INPUT.name());
                String externalStoragePath = uploadToExternalPayloadStorage(ExternalPayloadStorage.PayloadType.WORKFLOW_INPUT, workflowInputBytes, workflowInputSize);
                startWorkflowRequest.setExternalInputPayloadStoragePath(externalStoragePath);
                startWorkflowRequest.setInput(null);
            }
        }
    } catch (IOException e) {
        String errorMsg = String.format("Unable to start workflow:%s, version:%s", startWorkflowRequest.getName(), version);
        logger.error(errorMsg, e);
        MetricsContainer.incrementWorkflowStartErrorCount(startWorkflowRequest.getName(), e);
        throw new ConductorClientException(errorMsg, e);
    }
    try {
        return postForEntity("workflow", startWorkflowRequest, null, String.class, startWorkflowRequest.getName());
    } catch (ConductorClientException e) {
        String errorMsg = String.format("Unable to send start workflow request:%s, version:%s", startWorkflowRequest.getName(), version);
        logger.error(errorMsg, e);
        MetricsContainer.incrementWorkflowStartErrorCount(startWorkflowRequest.getName(), e);
        throw e;
    }
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ConductorClientException(com.netflix.conductor.client.exceptions.ConductorClientException)

Example 4 with ConductorClientException

use of com.netflix.conductor.client.exceptions.ConductorClientException in project conductor by Netflix.

the class AbstractHttpEndToEndTest method testUpdateWorkflowDefNameNull.

@Test(expected = ConductorClientException.class)
public void testUpdateWorkflowDefNameNull() {
    WorkflowDef workflowDef = new WorkflowDef();
    List<WorkflowDef> list = new ArrayList<>();
    list.add(workflowDef);
    try {
        metadataClient.updateWorkflowDefs(list);
    } catch (ConductorClientException e) {
        assertEquals(3, e.getValidationErrors().size());
        assertEquals(400, e.getStatus());
        assertEquals("Validation failed, check below errors for detail.", e.getMessage());
        assertFalse(e.isRetryable());
        List<ValidationError> errors = e.getValidationErrors();
        List<String> errorMessages = errors.stream().map(ValidationError::getMessage).collect(Collectors.toList());
        assertTrue(errorMessages.contains("WorkflowDef name cannot be null or empty"));
        assertTrue(errorMessages.contains("WorkflowTask list cannot be empty"));
        assertTrue(errorMessages.contains("ownerEmail cannot be empty"));
        throw e;
    }
}
Also used : WorkflowDef(com.netflix.conductor.common.metadata.workflow.WorkflowDef) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) ValidationError(com.netflix.conductor.common.validation.ValidationError) ConductorClientException(com.netflix.conductor.client.exceptions.ConductorClientException) Test(org.junit.Test)

Example 5 with ConductorClientException

use of com.netflix.conductor.client.exceptions.ConductorClientException in project conductor by Netflix.

the class AbstractHttpEndToEndTest method testEmptyCreateWorkflowDef.

@Test(expected = ConductorClientException.class)
public void testEmptyCreateWorkflowDef() {
    try {
        WorkflowDef workflowDef = new WorkflowDef();
        metadataClient.registerWorkflowDef(workflowDef);
    } catch (ConductorClientException e) {
        assertEquals(400, e.getStatus());
        assertEquals("Validation failed, check below errors for detail.", e.getMessage());
        assertFalse(e.isRetryable());
        List<ValidationError> errors = e.getValidationErrors();
        List<String> errorMessages = errors.stream().map(ValidationError::getMessage).collect(Collectors.toList());
        assertTrue(errorMessages.contains("WorkflowDef name cannot be null or empty"));
        assertTrue(errorMessages.contains("WorkflowTask list cannot be empty"));
        throw e;
    }
}
Also used : WorkflowDef(com.netflix.conductor.common.metadata.workflow.WorkflowDef) ArrayList(java.util.ArrayList) List(java.util.List) ValidationError(com.netflix.conductor.common.validation.ValidationError) ConductorClientException(com.netflix.conductor.client.exceptions.ConductorClientException) Test(org.junit.Test)

Aggregations

ConductorClientException (com.netflix.conductor.client.exceptions.ConductorClientException)14 Test (org.junit.Test)8 WorkflowDef (com.netflix.conductor.common.metadata.workflow.WorkflowDef)7 IOException (java.io.IOException)6 ArrayList (java.util.ArrayList)5 ValidationError (com.netflix.conductor.common.validation.ValidationError)4 List (java.util.List)4 WorkflowTask (com.netflix.conductor.common.metadata.workflow.WorkflowTask)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 HttpURLConnection (java.net.HttpURLConnection)2 MalformedURLException (java.net.MalformedURLException)2 URI (java.net.URI)2 URISyntaxException (java.net.URISyntaxException)2 URL (java.net.URL)2 MetadataClient (com.netflix.conductor.client.http.MetadataClient)1 TaskClient (com.netflix.conductor.client.http.TaskClient)1 Worker (com.netflix.conductor.client.worker.Worker)1 Task (com.netflix.conductor.common.metadata.tasks.Task)1 TaskDef (com.netflix.conductor.common.metadata.tasks.TaskDef)1 TaskResult (com.netflix.conductor.common.metadata.tasks.TaskResult)1