This is an automated email from the ASF dual-hosted git repository. jeremyross pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit eeb2bd5b324952e0730b31bf150fa5a00199408a Author: Jeremy Ross <[email protected]> AuthorDate: Tue May 24 21:10:35 2022 -0500 camel-salesforce: consolidate error parsing. --- .../internal/client/AbstractClientBase.java | 59 +++++++++++++++++- .../internal/client/DefaultCompositeApiClient.java | 24 -------- ...efaultCompositeSObjectCollectionsApiClient.java | 22 ------- .../internal/client/DefaultRestClient.java | 71 ---------------------- 4 files changed, 57 insertions(+), 119 deletions(-) diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java index 66f0610509e..0027da3822e 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/AbstractClientBase.java @@ -19,6 +19,7 @@ package org.apache.camel.component.salesforce.internal.client; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -39,12 +40,16 @@ import org.apache.camel.Exchange; import org.apache.camel.Message; import org.apache.camel.component.salesforce.SalesforceHttpClient; import org.apache.camel.component.salesforce.SalesforceLoginConfig; +import org.apache.camel.component.salesforce.api.NoSuchSObjectException; import org.apache.camel.component.salesforce.api.SalesforceException; +import org.apache.camel.component.salesforce.api.SalesforceMultipleChoicesException; import org.apache.camel.component.salesforce.api.TypeReferences; import org.apache.camel.component.salesforce.api.dto.RestError; +import org.apache.camel.component.salesforce.api.utils.JsonUtils; import org.apache.camel.component.salesforce.internal.PayloadFormat; import org.apache.camel.component.salesforce.internal.SalesforceSession; import org.apache.camel.support.service.ServiceSupport; +import org.apache.commons.io.IOUtils; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpContentResponse; import org.eclipse.jetty.client.api.ContentProvider; @@ -82,7 +87,8 @@ public abstract class AbstractClientBase extends ServiceSupport private Phaser inflightRequests; - private long terminationTimeout; + private final long terminationTimeout; + private final ObjectMapper objectMapper; public AbstractClientBase(String version, SalesforceSession session, SalesforceHttpClient httpClient, SalesforceLoginConfig loginConfig) { @@ -96,6 +102,7 @@ public abstract class AbstractClientBase extends ServiceSupport this.httpClient = httpClient; this.loginConfig = loginConfig; this.terminationTimeout = terminationTimeout; + this.objectMapper = JsonUtils.createObjectMapper(); } @Override @@ -292,7 +299,55 @@ public abstract class AbstractClientBase extends ServiceSupport protected abstract void setAccessToken(Request request); - protected abstract SalesforceException createRestException(Response response, InputStream responseContent); + protected SalesforceException createRestException(Response response, InputStream responseContent) { + // get status code and reason phrase + final int statusCode = response.getStatus(); + String reason = response.getReason(); + if (reason == null || reason.isEmpty()) { + reason = HttpStatus.getMessage(statusCode); + } + try { + if (responseContent != null && responseContent.available() > 0) { + final List<String> choices; + // return list of choices as error message for 300 + if (statusCode == HttpStatus.MULTIPLE_CHOICES_300) { + choices = objectMapper.readValue(responseContent, TypeReferences.STRING_LIST_TYPE); + return new SalesforceMultipleChoicesException(reason, statusCode, choices); + } else { + List<RestError> restErrors = null; + String body = null; + try { + restErrors = readErrorsFrom(responseContent, objectMapper); + } catch (IOException ignored) { + // ok. could be a custom response + } + try { + responseContent.reset(); + body = IOUtils.toString(responseContent, StandardCharsets.UTF_8); + responseContent.reset(); + } catch (Throwable t) { + log.warn("Unable to reset HTTP response content input stream."); + } + if (statusCode == HttpStatus.NOT_FOUND_404) { + return new NoSuchSObjectException(restErrors); + } + + return new SalesforceException( + restErrors, statusCode, + "Unexpected error: " + reason + ". See exception `errors` property for detail. " + body, + responseContent); + } + } + } catch (IOException | RuntimeException e) { + // log and ignore + String msg = "Unexpected Error parsing error response body + [" + responseContent + "] : " + + e.getMessage(); + log.warn(msg, e); + } + + // just report HTTP status info + return new SalesforceException("Unexpected error: " + reason + ", with content: " + responseContent, statusCode); + } static Map<String, String> determineHeadersFrom(final Response response) { final HttpFields headers = response.getHeaders(); diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeApiClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeApiClient.java index 29e7d1e4766..9b05fa62240 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeApiClient.java +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeApiClient.java @@ -31,9 +31,7 @@ import com.fasterxml.jackson.databind.type.CollectionType; import org.apache.camel.component.salesforce.SalesforceEndpointConfig; import org.apache.camel.component.salesforce.SalesforceHttpClient; import org.apache.camel.component.salesforce.SalesforceLoginConfig; -import org.apache.camel.component.salesforce.api.NoSuchSObjectException; import org.apache.camel.component.salesforce.api.SalesforceException; -import org.apache.camel.component.salesforce.api.dto.RestError; import org.apache.camel.component.salesforce.api.dto.composite.SObjectBatch; import org.apache.camel.component.salesforce.api.dto.composite.SObjectBatchResponse; import org.apache.camel.component.salesforce.api.dto.composite.SObjectComposite; @@ -47,11 +45,9 @@ import org.apache.camel.util.IOHelper; import org.apache.camel.util.ObjectHelper; import org.eclipse.jetty.client.api.ContentProvider; import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.util.InputStreamContentProvider; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; -import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.util.StringUtil; public class DefaultCompositeApiClient extends AbstractClientBase implements CompositeApiClient { @@ -230,26 +226,6 @@ public class DefaultCompositeApiClient extends AbstractClientBase implements Com return servicesDataUrl() + "v" + version + "/"; } - @Override - protected SalesforceException createRestException(final Response response, final InputStream responseContent) { - final List<RestError> errors; - try { - errors = readErrorsFrom(responseContent, mapper); - } catch (final IOException e) { - return new SalesforceException("Unable to read error response", e); - } - - final int status = response.getStatus(); - if (status == HttpStatus.NOT_FOUND_404) { - return new NoSuchSObjectException(errors); - } - - final String reason = response.getReason(); - - return new SalesforceException( - errors, status, "Unexpected error: " + reason + ". See exception `errors` property for detail."); - } - @Override protected void setAccessToken(final Request request) { request.getHeaders().put("Authorization", "Bearer " + accessToken); diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeSObjectCollectionsApiClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeSObjectCollectionsApiClient.java index 953ac60e9d0..c8a5666e5cb 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeSObjectCollectionsApiClient.java +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultCompositeSObjectCollectionsApiClient.java @@ -30,25 +30,20 @@ import com.fasterxml.jackson.databind.type.CollectionType; import org.apache.camel.component.salesforce.SalesforceEndpointConfig; import org.apache.camel.component.salesforce.SalesforceHttpClient; import org.apache.camel.component.salesforce.SalesforceLoginConfig; -import org.apache.camel.component.salesforce.api.NoSuchSObjectException; import org.apache.camel.component.salesforce.api.SalesforceException; import org.apache.camel.component.salesforce.api.dto.DeleteSObjectResult; -import org.apache.camel.component.salesforce.api.dto.RestError; import org.apache.camel.component.salesforce.api.dto.SaveSObjectResult; import org.apache.camel.component.salesforce.api.dto.UpsertSObjectResult; import org.apache.camel.component.salesforce.api.dto.composite.SObjectCollection; import org.apache.camel.component.salesforce.api.utils.JsonUtils; -import org.apache.camel.component.salesforce.internal.PayloadFormat; import org.apache.camel.component.salesforce.internal.SalesforceSession; import org.apache.camel.component.salesforce.internal.dto.composite.RetrieveSObjectCollectionsDto; import org.apache.camel.util.IOHelper; import org.apache.camel.util.ObjectHelper; import org.eclipse.jetty.client.api.ContentProvider; import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.util.InputStreamContentProvider; import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.http.HttpStatus; public class DefaultCompositeSObjectCollectionsApiClient extends AbstractClientBase implements CompositeSObjectCollectionsApiClient { @@ -185,23 +180,6 @@ public class DefaultCompositeSObjectCollectionsApiClient extends AbstractClientB }); } - @Override - protected SalesforceException createRestException(final Response response, final InputStream responseContent) { - final List<RestError> errors; - try { - errors = readErrorsFrom(responseContent, PayloadFormat.JSON, mapper); - } catch (final IOException e) { - return new SalesforceException("Unable to read error response", e); - } - - final int status = response.getStatus(); - if (status == HttpStatus.NOT_FOUND_404) { - return new NoSuchSObjectException(errors); - } - final String reason = response.getReason(); - return new SalesforceException(errors, status, "Unexpected error: " + reason); - } - @Override protected void setAccessToken(final Request request) { request.getHeaders().put("Authorization", "Bearer " + accessToken); diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java index a07d98dfef0..fc1329186bf 100644 --- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java +++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/DefaultRestClient.java @@ -16,36 +16,25 @@ */ package org.apache.camel.component.salesforce.internal.client; -import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; -import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.camel.component.salesforce.SalesforceHttpClient; import org.apache.camel.component.salesforce.SalesforceLoginConfig; -import org.apache.camel.component.salesforce.api.NoSuchSObjectException; import org.apache.camel.component.salesforce.api.SalesforceException; -import org.apache.camel.component.salesforce.api.SalesforceMultipleChoicesException; -import org.apache.camel.component.salesforce.api.TypeReferences; -import org.apache.camel.component.salesforce.api.dto.RestError; -import org.apache.camel.component.salesforce.api.utils.JsonUtils; import org.apache.camel.component.salesforce.internal.SalesforceSession; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.URISupport; -import org.apache.commons.io.IOUtils; import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.util.InputStreamContentProvider; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; -import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.util.StringUtil; public class DefaultRestClient extends AbstractClientBase implements RestClient { @@ -55,14 +44,10 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient private static final String TOKEN_PREFIX = "Bearer "; private static final String SERVICES_APEXREST = "/services/apexrest/"; - private ObjectMapper objectMapper; - public DefaultRestClient(final SalesforceHttpClient httpClient, final String version, final SalesforceSession session, final SalesforceLoginConfig loginConfig) throws SalesforceException { super(version, session, httpClient, loginConfig); - - this.objectMapper = JsonUtils.createObjectMapper(); } @Override @@ -75,62 +60,6 @@ public class DefaultRestClient extends AbstractClientBase implements RestClient super.doHttpRequest(request, callback); } - @Override - protected SalesforceException createRestException(Response response, InputStream responseContent) { - // get status code and reason phrase - final int statusCode = response.getStatus(); - String reason = response.getReason(); - if (reason == null || reason.isEmpty()) { - reason = HttpStatus.getMessage(statusCode); - } - try { - if (responseContent != null && responseContent.available() > 0) { - final List<String> choices; - // return list of choices as error message for 300 - if (statusCode == HttpStatus.MULTIPLE_CHOICES_300) { - choices = objectMapper.readValue(responseContent, TypeReferences.STRING_LIST_TYPE); - return new SalesforceMultipleChoicesException(reason, statusCode, choices); - } else { - List<RestError> restErrors = null; - String body = null; - try { - restErrors = readErrorsFrom(responseContent, objectMapper); - } catch (IOException ignored) { - // ok. could be a custom response - } - try { - responseContent.reset(); - body = IOUtils.toString(responseContent, StandardCharsets.UTF_8); - responseContent.reset(); - } catch (Throwable t) { - log.warn("Unable to reset HTTP response content input stream."); - } - if (statusCode == HttpStatus.NOT_FOUND_404) { - return new NoSuchSObjectException(restErrors); - } - - return new SalesforceException( - restErrors, statusCode, - "Unexpected error: " + reason + ". See exception `errors` property for detail. " + body, - responseContent); - } - } - } catch (IOException e) { - // log and ignore - String msg = "Unexpected Error parsing error response body + [" + responseContent + "] : " - + e.getMessage(); - log.warn(msg, e); - } catch (RuntimeException e) { - // log and ignore - String msg = "Unexpected Error parsing error response body + [" + responseContent + "] : " - + e.getMessage(); - log.warn(msg, e); - } - - // just report HTTP status info - return new SalesforceException("Unexpected error: " + reason + ", with content: " + responseContent, statusCode); - } - @Override public void approval(final InputStream request, Map<String, List<String>> headers, final ResponseCallback callback) { final Request post = getRequest(HttpMethod.POST, versionUrl() + "process/approvals/", headers);
