You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by je...@apache.org on 2021/12/15 20:12:18 UTC

[camel] branch main updated (0bd749e -> 5882290)

This is an automated email from the ASF dual-hosted git repository.

jeremyross pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from 0bd749e  Regen for commit ca1b9fe47a297fa1524687c1597da8fb23954d2e
     new c087835  CAMEL-17344: camel-salesforce: swallowing exceptions
     new 5882290  CAMEL-17346: camel-salesforce: expired passwords

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 ...efaultCompositeSObjectCollectionsApiClient.java | 34 +++++++++++++---------
 .../internal/client/SalesforceSecurityHandler.java | 34 ++++++++++++++++++++++
 .../CompositeSObjectCollectionsProcessor.java      |  2 +-
 3 files changed, 55 insertions(+), 15 deletions(-)

[camel] 02/02: CAMEL-17346: camel-salesforce: expired passwords

Posted by je...@apache.org.
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 58822906704efd99470aec37430a12afa86e3dbc
Author: Jeremy Ross <je...@gmail.com>
AuthorDate: Wed Dec 15 13:36:51 2021 -0600

    CAMEL-17346: camel-salesforce: expired passwords
    
    Better handling for 401 expired password.
---
 .../internal/client/SalesforceSecurityHandler.java | 34 ++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityHandler.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityHandler.java
index 62633be..375cfda 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityHandler.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/client/SalesforceSecurityHandler.java
@@ -16,10 +16,15 @@
  */
 package org.apache.camel.component.salesforce.internal.client;
 
+import java.io.IOException;
 import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.camel.component.salesforce.SalesforceHttpClient;
 import org.apache.camel.component.salesforce.api.SalesforceException;
+import org.apache.camel.component.salesforce.api.dto.RestError;
 import org.apache.camel.component.salesforce.internal.SalesforceSession;
 import org.eclipse.jetty.client.HttpContentResponse;
 import org.eclipse.jetty.client.HttpConversation;
@@ -45,12 +50,14 @@ public class SalesforceSecurityHandler implements ProtocolHandler {
     private static final Logger LOG = LoggerFactory.getLogger(SalesforceSecurityHandler.class);
 
     private static final String AUTHENTICATION_RETRIES_ATTRIBUTE = SalesforceSecurityHandler.class.getName().concat(".retries");
+    private static final String EXPIRED_PASSWORD_CODE = "INVALID_OPERATION_WITH_EXPIRED_PASSWORD";
 
     private final SalesforceHttpClient httpClient;
     private final SalesforceSession session;
     private final int maxAuthenticationRetries;
     private final int maxContentLength;
     private final ResponseNotifier notifier;
+    private final ObjectMapper objectMapper = new ObjectMapper();
 
     public SalesforceSecurityHandler(SalesforceHttpClient httpClient) {
 
@@ -159,6 +166,22 @@ public class SalesforceSecurityHandler implements ProtocolHandler {
             // request failed authentication?
             if (status == HttpStatus.UNAUTHORIZED_401) {
 
+                // Salesforce will allow successful login with an expired password, but any subsequent
+                // API calls will fail with a 401 and message about expired password.
+                // It's fatal. User must reset password.
+                List<RestError> errors = Collections.emptyList();
+                try {
+                    errors = client.readErrorsFrom(getContentAsInputStream(), objectMapper);
+                } catch (IOException e) {
+                    LOG.warn("Unable to deserialize errors from response body.");
+                }
+                if (errors.stream().anyMatch(error -> EXPIRED_PASSWORD_CODE.equals(error.getErrorCode()))) {
+                    SalesforceException salesforceException = createSalesforceException(client, status,
+                            reason);
+                    forwardFailureComplete(request, null, response, salesforceException);
+                    return;
+                }
+
                 // REST token expiry
                 LOG.warn("Retrying on Salesforce authentication error [{}]: [{}]", status, reason);
 
@@ -188,6 +211,16 @@ public class SalesforceSecurityHandler implements ProtocolHandler {
             }
         }
 
+        private SalesforceException createSalesforceException(AbstractClientBase client, int statusCode, String reason) {
+            List<RestError> restErrors = Collections.emptyList();
+            try {
+                restErrors = client.readErrorsFrom(getContentAsInputStream(), new ObjectMapper());
+            } catch (IOException e) {
+                LOG.warn("Unable to deserialize errors from response body.");
+            }
+            return new SalesforceException(restErrors, statusCode);
+        }
+
         protected void retryOnFailure(
                 SalesforceHttpRequest request, HttpConversation conversation, Integer retries, AbstractClientBase client,
                 Throwable failure) {
@@ -286,6 +319,7 @@ public class SalesforceSecurityHandler implements ProtocolHandler {
             notifier.forwardFailureComplete(conversation.getResponseListeners(), request, requestFailure, response,
                     responseFailure);
         }
+
     }
 
     // no @Override annotation here to keep it compatible with Jetty 9.2,

[camel] 01/02: CAMEL-17344: camel-salesforce: swallowing exceptions

Posted by je...@apache.org.
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 c08783523cdc4e2e4f2b5ded56f0a27e4e72c024
Author: Jeremy Ross <je...@gmail.com>
AuthorDate: Wed Dec 15 12:24:33 2021 -0600

    CAMEL-17344: camel-salesforce: swallowing exceptions
    
    collections operations swallow exceptions
---
 ...efaultCompositeSObjectCollectionsApiClient.java | 34 +++++++++++++---------
 .../CompositeSObjectCollectionsProcessor.java      |  2 +-
 2 files changed, 21 insertions(+), 15 deletions(-)

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 75c575a..953ac60 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
@@ -85,11 +85,11 @@ public class DefaultCompositeSObjectCollectionsApiClient extends AbstractClientB
         doHttpRequest(request, new ClientResponseCallback() {
             @Override
             public void onResponse(InputStream response, Map<String, String> headers, SalesforceException ex) {
-                callback.onResponse(
-                        tryToReadListResponse(
-                                sobjectType, response),
-                        headers,
-                        ex);
+                Optional<List<T>> body = Optional.empty();
+                if (ex == null) {
+                    body = tryToReadListResponse(sobjectType, response);
+                }
+                callback.onResponse(body, headers, ex);
             }
         });
     }
@@ -124,9 +124,11 @@ public class DefaultCompositeSObjectCollectionsApiClient extends AbstractClientB
         doHttpRequest(request, new ClientResponseCallback() {
             @Override
             public void onResponse(InputStream response, Map<String, String> headers, SalesforceException ex) {
-                callback.onResponse(
-                        tryToReadListResponse(SaveSObjectResult.class, response),
-                        headers, ex);
+                Optional<List<SaveSObjectResult>> body = Optional.empty();
+                if (ex == null) {
+                    body = tryToReadListResponse(SaveSObjectResult.class, response);
+                }
+                callback.onResponse(body, headers, ex);
             }
         });
     }
@@ -152,9 +154,11 @@ public class DefaultCompositeSObjectCollectionsApiClient extends AbstractClientB
         doHttpRequest(request, new ClientResponseCallback() {
             @Override
             public void onResponse(InputStream response, Map<String, String> headers, SalesforceException ex) {
-                callback.onResponse(
-                        tryToReadListResponse(UpsertSObjectResult.class, response),
-                        headers, ex);
+                Optional<List<UpsertSObjectResult>> body = Optional.empty();
+                if (ex == null) {
+                    body = tryToReadListResponse(UpsertSObjectResult.class, response);
+                }
+                callback.onResponse(body, headers, ex);
             }
         });
     }
@@ -172,9 +176,11 @@ public class DefaultCompositeSObjectCollectionsApiClient extends AbstractClientB
         doHttpRequest(request, new ClientResponseCallback() {
             @Override
             public void onResponse(InputStream response, Map<String, String> headers, SalesforceException ex) {
-                callback.onResponse(
-                        tryToReadListResponse(DeleteSObjectResult.class, response),
-                        headers, ex);
+                Optional<List<DeleteSObjectResult>> body = Optional.empty();
+                if (ex == null) {
+                    body = tryToReadListResponse(DeleteSObjectResult.class, response);
+                }
+                callback.onResponse(body, headers, ex);
             }
         });
     }
diff --git a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/CompositeSObjectCollectionsProcessor.java b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/CompositeSObjectCollectionsProcessor.java
index 98319a7..03d6a20 100644
--- a/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/CompositeSObjectCollectionsProcessor.java
+++ b/components/camel-salesforce/camel-salesforce-component/src/main/java/org/apache/camel/component/salesforce/internal/processor/CompositeSObjectCollectionsProcessor.java
@@ -172,7 +172,7 @@ public class CompositeSObjectCollectionsProcessor extends AbstractSalesforceProc
             final Exchange exchange, final Optional<? extends List<?>> responseBody, final Map<String, String> headers,
             final SalesforceException exception, final AsyncCallback callback) {
         try {
-            if (!responseBody.isPresent()) {
+            if (exception != null) {
                 exchange.setException(exception);
             } else {
                 Message in = exchange.getIn();