You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2020/02/20 05:19:30 UTC

[camel] 01/02: CAMEL-6950: camel-sjms make the backoff a long so its simple to configure. Also add better logging when refill happens.

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

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 794271266d27033ea19e0b31134047f61051d82a
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Feb 20 06:15:50 2020 +0100

    CAMEL-6950: camel-sjms make the backoff a long so its simple to configure. Also add better logging when refill happens.
---
 .../component/sjms/SjmsComponentConfigurer.java    |  4 +++
 .../component/sjms/SjmsEndpointConfigurer.java     |  2 +-
 .../org/apache/camel/component/sjms/sjms.json      |  6 ++--
 .../camel-sjms/src/main/docs/sjms-component.adoc   |  8 ++++--
 .../apache/camel/component/sjms/SjmsComponent.java | 33 ++++++++++++++++++++--
 .../apache/camel/component/sjms/SjmsConsumer.java  | 12 ++++++--
 .../apache/camel/component/sjms/SjmsEndpoint.java  | 18 +++++++-----
 .../component/dsl/SjmsComponentBuilderFactory.java | 26 +++++++++++++++++
 8 files changed, 91 insertions(+), 18 deletions(-)

diff --git a/components/camel-sjms/src/generated/java/org/apache/camel/component/sjms/SjmsComponentConfigurer.java b/components/camel-sjms/src/generated/java/org/apache/camel/component/sjms/SjmsComponentConfigurer.java
index 8d989a6..ca1d0c6 100644
--- a/components/camel-sjms/src/generated/java/org/apache/camel/component/sjms/SjmsComponentConfigurer.java
+++ b/components/camel-sjms/src/generated/java/org/apache/camel/component/sjms/SjmsComponentConfigurer.java
@@ -19,6 +19,10 @@ public class SjmsComponentConfigurer extends PropertyConfigurerSupport implement
         case "connectionCount": target.setConnectionCount(property(camelContext, java.lang.Integer.class, value)); return true;
         case "bridgeerrorhandler":
         case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
+        case "reconnectbackoff":
+        case "reconnectBackOff": target.setReconnectBackOff(property(camelContext, long.class, value)); return true;
+        case "reconnectonerror":
+        case "reconnectOnError": target.setReconnectOnError(property(camelContext, boolean.class, value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
         case "basicpropertybinding":
diff --git a/components/camel-sjms/src/generated/java/org/apache/camel/component/sjms/SjmsEndpointConfigurer.java b/components/camel-sjms/src/generated/java/org/apache/camel/component/sjms/SjmsEndpointConfigurer.java
index 8b53629..1f1bfca 100644
--- a/components/camel-sjms/src/generated/java/org/apache/camel/component/sjms/SjmsEndpointConfigurer.java
+++ b/components/camel-sjms/src/generated/java/org/apache/camel/component/sjms/SjmsEndpointConfigurer.java
@@ -24,7 +24,7 @@ public class SjmsEndpointConfigurer extends PropertyConfigurerSupport implements
         case "durablesubscriptionid":
         case "durableSubscriptionId": target.setDurableSubscriptionId(property(camelContext, java.lang.String.class, value)); return true;
         case "reconnectbackoff":
-        case "reconnectBackOff": target.setReconnectBackOff(property(camelContext, org.apache.camel.util.backoff.BackOff.class, value)); return true;
+        case "reconnectBackOff": target.setReconnectBackOff(property(camelContext, long.class, value)); return true;
         case "reconnectonerror":
         case "reconnectOnError": target.setReconnectOnError(property(camelContext, boolean.class, value)); return true;
         case "synchronous": target.setSynchronous(property(camelContext, boolean.class, value)); return true;
diff --git a/components/camel-sjms/src/generated/resources/org/apache/camel/component/sjms/sjms.json b/components/camel-sjms/src/generated/resources/org/apache/camel/component/sjms/sjms.json
index 76fa614..ec09762 100644
--- a/components/camel-sjms/src/generated/resources/org/apache/camel/component/sjms/sjms.json
+++ b/components/camel-sjms/src/generated/resources/org/apache/camel/component/sjms/sjms.json
@@ -21,6 +21,8 @@
   "componentProperties": {
     "connectionCount": { "kind": "property", "displayName": "Connection Count", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "secret": false, "defaultValue": "1", "description": "The maximum number of connections available to endpoints started under this component" },
     "bridgeErrorHandler": { "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by [...]
+    "reconnectBackOff": { "kind": "property", "displayName": "Reconnect Back Off", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "secret": false, "defaultValue": "5000", "description": "Backoff in millis on consumer pool reconnection attempts" },
+    "reconnectOnError": { "kind": "property", "displayName": "Reconnect On Error", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": "true", "description": "Try to apply reconnection logic on consumer pool" },
     "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the r [...]
     "basicPropertyBinding": { "kind": "property", "displayName": "Basic Property Binding", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities" },
     "connectionClientId": { "kind": "property", "displayName": "Connection Client Id", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "The client ID to use when creating javax.jms.Connection when using the default org.apache.camel.component.sjms.jms.ConnectionFactoryResource." },
@@ -44,8 +46,8 @@
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled b [...]
     "consumerCount": { "kind": "parameter", "displayName": "Consumer Count", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "secret": false, "defaultValue": "1", "description": "Sets the number of consumer listeners used for this endpoint." },
     "durableSubscriptionId": { "kind": "parameter", "displayName": "Durable Subscription Id", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the durable subscription Id required for durable topics." },
-    "reconnectBackOff": { "kind": "parameter", "displayName": "Reconnect Back Off", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "org.apache.camel.util.backoff.BackOff", "deprecated": false, "secret": false, "description": "Backoff policy on consumer pool reconnection. Default value notice: Default backoff is infinite retries with 5 seconds delay" },
-    "reconnectOnError": { "kind": "parameter", "displayName": "Reconnect On Error", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Try to apply reconnection logic on consumer pool" },
+    "reconnectBackOff": { "kind": "parameter", "displayName": "Reconnect Back Off", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "secret": false, "defaultValue": "5000", "description": "Backoff in millis on consumer pool reconnection attempts" },
+    "reconnectOnError": { "kind": "parameter", "displayName": "Reconnect On Error", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": "true", "description": "Try to apply reconnection logic on consumer pool" },
     "synchronous": { "kind": "parameter", "displayName": "Synchronous", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": "true", "description": "Sets whether synchronous processing should be strictly used or Camel is allowed to use asynchronous processing (if supported)." },
     "exceptionHandler": { "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", "InOptionalOut" ], "deprecated": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
diff --git a/components/camel-sjms/src/main/docs/sjms-component.adoc b/components/camel-sjms/src/main/docs/sjms-component.adoc
index a780e22..d09be19 100644
--- a/components/camel-sjms/src/main/docs/sjms-component.adoc
+++ b/components/camel-sjms/src/main/docs/sjms-component.adoc
@@ -85,7 +85,7 @@ You append query options to the URI using the following format,
 == Component Options and Configurations
 
 // component options: START
-The Simple JMS component supports 17 options, which are listed below.
+The Simple JMS component supports 19 options, which are listed below.
 
 
 
@@ -94,6 +94,8 @@ The Simple JMS component supports 17 options, which are listed below.
 | Name | Description | Default | Type
 | *connectionCount* (common) | The maximum number of connections available to endpoints started under this component | 1 | Integer
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
+| *reconnectBackOff* (consumer) | Backoff in millis on consumer pool reconnection attempts | 5000 | long
+| *reconnectOnError* (consumer) | Try to apply reconnection logic on consumer pool | true | boolean
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
 | *basicPropertyBinding* (advanced) | Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | boolean
 | *connectionClientId* (advanced) | The client ID to use when creating javax.jms.Connection when using the default org.apache.camel.component.sjms.jms.ConnectionFactoryResource. |  | String
@@ -143,8 +145,8 @@ with the following path and query parameters:
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
 | *consumerCount* (consumer) | Sets the number of consumer listeners used for this endpoint. | 1 | int
 | *durableSubscriptionId* (consumer) | Sets the durable subscription Id required for durable topics. |  | String
-| *reconnectBackOff* (consumer) | Backoff policy on consumer pool reconnection. Default value notice: Default backoff is infinite retries with 5 seconds delay |  | BackOff
-| *reconnectOnError* (consumer) | Try to apply reconnection logic on consumer pool | false | boolean
+| *reconnectBackOff* (consumer) | Backoff in millis on consumer pool reconnection attempts | 5000 | long
+| *reconnectOnError* (consumer) | Try to apply reconnection logic on consumer pool | true | boolean
 | *synchronous* (consumer) | Sets whether synchronous processing should be strictly used or Camel is allowed to use asynchronous processing (if supported). | true | boolean
 | *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. The value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
diff --git a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsComponent.java b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsComponent.java
index f221492..3abfd4c 100644
--- a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsComponent.java
+++ b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsComponent.java
@@ -16,11 +16,10 @@
  */
 package org.apache.camel.component.sjms;
 
+import javax.jms.ConnectionFactory;
 import java.util.Map;
 import java.util.concurrent.ExecutorService;
 
-import javax.jms.ConnectionFactory;
-
 import org.apache.camel.CamelException;
 import org.apache.camel.Endpoint;
 import org.apache.camel.ExchangePattern;
@@ -78,6 +77,10 @@ public class SjmsComponent extends HeaderFilterStrategyComponent {
     @Metadata(label = "advanced", defaultValue = "5000", description = "The max wait time in millis to block and wait on free connection when the pool"
         + " is exhausted when using the default {@link org.apache.camel.component.sjms.jms.ConnectionFactoryResource}.")
     private long connectionMaxWait = 5000;
+    @Metadata(label = "consumer", description = "Try to apply reconnection logic on consumer pool", defaultValue = "true")
+    private boolean reconnectOnError = true;
+    @Metadata(label = "consumer", description = "Backoff in millis on consumer pool reconnection attempts", defaultValue = "5000")
+    private long reconnectBackOff = 5000;
 
     public SjmsComponent() {
     }
@@ -89,7 +92,6 @@ public class SjmsComponent extends HeaderFilterStrategyComponent {
     protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
         validateMepAndReplyTo(parameters);
         SjmsEndpoint endpoint = createSjmsEndpoint(uri, remaining);
-        setProperties(endpoint, parameters);
         if (endpoint.isTransacted()) {
             endpoint.setSynchronous(true);
         }
@@ -105,6 +107,9 @@ public class SjmsComponent extends HeaderFilterStrategyComponent {
         if (messageCreatedStrategy != null) {
             endpoint.setMessageCreatedStrategy(messageCreatedStrategy);
         }
+        endpoint.setReconnectOnError(reconnectOnError);
+        endpoint.setReconnectBackOff(reconnectBackOff);
+        setProperties(endpoint, parameters);
         return endpoint;
     }
 
@@ -320,4 +325,26 @@ public class SjmsComponent extends HeaderFilterStrategyComponent {
     public void setConnectionMaxWait(long connectionMaxWait) {
         this.connectionMaxWait = connectionMaxWait;
     }
+
+    public boolean isReconnectOnError() {
+        return reconnectOnError;
+    }
+
+    /**
+     * Try to apply reconnection logic on consumer pool
+     */
+    public void setReconnectOnError(boolean reconnectOnError) {
+        this.reconnectOnError = reconnectOnError;
+    }
+
+    public long getReconnectBackOff() {
+        return reconnectBackOff;
+    }
+
+    /**
+     * Backoff in millis on consumer pool reconnection attempts
+     */
+    public void setReconnectBackOff(long reconnectBackOff) {
+        this.reconnectBackOff = reconnectBackOff;
+    }
 }
diff --git a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsConsumer.java b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsConsumer.java
index 7bc2100..a8bc17c 100644
--- a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsConsumer.java
+++ b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsConsumer.java
@@ -48,6 +48,7 @@ import org.apache.camel.component.sjms.tx.SessionBatchTransactionSynchronization
 import org.apache.camel.component.sjms.tx.SessionTransactionSynchronization;
 import org.apache.camel.spi.Synchronization;
 import org.apache.camel.support.DefaultConsumer;
+import org.apache.camel.util.backoff.BackOff;
 import org.apache.camel.util.backoff.BackOffTimer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -380,18 +381,25 @@ public class SjmsConsumer extends DefaultConsumer {
     }
 
     private boolean refillPool(BackOffTimer.Task task) {
+        LOG.debug("Refill consumers pool task running");
         try {
             fillConsumersPool();
+            LOG.info("Refill consumers pool completed (attempt: {})", task.getCurrentAttempts());
             return false;
         } catch (Exception ex) {
-            LOG.error("Cannot refill consumers pool, attempt " + task.getCurrentAttempts(), ex);
+            LOG.warn("Refill consumers pool failed (attempt: {}) due to: {}. Will try again in {} millis. (stacktrace in DEBUG level)",
+                    task.getCurrentAttempts(), ex.getMessage(), task.getCurrentDelay());
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Refill consumers pool failed", ex);
+            }
         }
         return true;
     }
 
     private void scheduleRefill() {
         if (rescheduleTask == null || rescheduleTask.getStatus() != BackOffTimer.Task.Status.Active) {
-            rescheduleTask = new BackOffTimer(scheduler).schedule(getEndpoint().getReconnectBackOff(), this::refillPool);
+            BackOff backOff = BackOff.builder().delay(getEndpoint().getReconnectBackOff()).build();
+            rescheduleTask = new BackOffTimer(scheduler).schedule(backOff, this::refillPool);
         }
     }
 
diff --git a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsEndpoint.java b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsEndpoint.java
index d2926fc..acd538a 100644
--- a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsEndpoint.java
+++ b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsEndpoint.java
@@ -183,11 +183,10 @@ public class SjmsEndpoint extends DefaultEndpoint implements AsyncEndpoint, Mult
     @UriParam(defaultValue = "true", label = "consumer,logging",
             description = "Allows to control whether stacktraces should be logged or not, by the default errorHandler.")
     private boolean errorHandlerLogStackTrace = true;
-    @UriParam(label = "consumer", description = "Try to apply reconnection logic on consumer pool")
+    @UriParam(label = "consumer", description = "Try to apply reconnection logic on consumer pool", defaultValue = "true")
     private boolean reconnectOnError = true;
-    @UriParam(label = "consumer", description = "Backoff policy on consumer pool reconnection",
-        defaultValueNote = "Default backoff is infinite retries with 5 seconds delay")
-    private BackOff reconnectBackOff = BackOff.builder().delay(Duration.ofSeconds(5)).build();
+    @UriParam(label = "consumer", description = "Backoff in millis on consumer pool reconnection attempts", defaultValue = "5000")
+    private long reconnectBackOff = 5000;
 
     private volatile boolean closeConnectionResource;
 
@@ -763,20 +762,25 @@ public class SjmsEndpoint extends DefaultEndpoint implements AsyncEndpoint, Mult
         this.jmsObjectFactory = jmsObjectFactory;
     }
 
-
     public boolean isReconnectOnError() {
         return reconnectOnError;
     }
 
+    /**
+     * Try to apply reconnection logic on consumer pool
+     */
     public void setReconnectOnError(boolean reconnectOnError) {
         this.reconnectOnError = reconnectOnError;
     }
 
-    public BackOff getReconnectBackOff() {
+    public long getReconnectBackOff() {
         return reconnectBackOff;
     }
 
-    public void setReconnectBackOff(BackOff reconnectBackOff) {
+    /**
+     * Backoff in millis on consumer pool reconnection attempts
+     */
+    public void setReconnectBackOff(long reconnectBackOff) {
         this.reconnectBackOff = reconnectBackOff;
     }
 }
diff --git a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SjmsComponentBuilderFactory.java b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SjmsComponentBuilderFactory.java
index 8b04f52..84a0d73 100644
--- a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SjmsComponentBuilderFactory.java
+++ b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SjmsComponentBuilderFactory.java
@@ -82,6 +82,30 @@ public interface SjmsComponentBuilderFactory {
             return this;
         }
         /**
+         * Backoff in millis on consumer pool reconnection attempts.
+         * 
+         * The option is a: <code>long</code> type.
+         * 
+         * Default: 5000
+         * Group: consumer
+         */
+        default SjmsComponentBuilder reconnectBackOff(long reconnectBackOff) {
+            doSetProperty("reconnectBackOff", reconnectBackOff);
+            return this;
+        }
+        /**
+         * Try to apply reconnection logic on consumer pool.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: true
+         * Group: consumer
+         */
+        default SjmsComponentBuilder reconnectOnError(boolean reconnectOnError) {
+            doSetProperty("reconnectOnError", reconnectOnError);
+            return this;
+        }
+        /**
          * Whether the producer should be started lazy (on the first message).
          * By starting lazy you can use this to allow CamelContext and routes to
          * startup in situations where a producer may otherwise fail during
@@ -325,6 +349,8 @@ public interface SjmsComponentBuilderFactory {
             switch (name) {
             case "connectionCount": ((SjmsComponent) component).setConnectionCount((java.lang.Integer) value); return true;
             case "bridgeErrorHandler": ((SjmsComponent) component).setBridgeErrorHandler((boolean) value); return true;
+            case "reconnectBackOff": ((SjmsComponent) component).setReconnectBackOff((long) value); return true;
+            case "reconnectOnError": ((SjmsComponent) component).setReconnectOnError((boolean) value); return true;
             case "lazyStartProducer": ((SjmsComponent) component).setLazyStartProducer((boolean) value); return true;
             case "basicPropertyBinding": ((SjmsComponent) component).setBasicPropertyBinding((boolean) value); return true;
             case "connectionClientId": ((SjmsComponent) component).setConnectionClientId((java.lang.String) value); return true;