Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

GPRABBITMQ-30 - retryAttempts is now configurable

  • Loading branch information...
commit e8c0a2db3a716cab43ddf5aa9be0d4eb4f052796 1 parent c935b23
Jeff Scott Brown jeffbrown authored
52 RabbitmqGrailsPlugin.groovy
View
@@ -1,5 +1,6 @@
import org.codehaus.groovy.grails.commons.ServiceArtefactHandler
import org.grails.rabbitmq.AutoQueueMessageListenerContainer
+import org.grails.rabbitmq.RabbitConfigurationHolder
import org.grails.rabbitmq.RabbitDynamicMethods
import org.grails.rabbitmq.RabbitErrorHandler
import org.grails.rabbitmq.RabbitQueueBuilder
@@ -8,10 +9,25 @@ import org.springframework.amqp.core.Binding
import org.springframework.amqp.core.Queue
import org.springframework.amqp.rabbit.core.RabbitAdmin
import org.springframework.amqp.rabbit.core.RabbitTemplate
-import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter
+import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer
+import org.springframework.retry.backoff.FixedBackOffPolicy;
+//import org.springframework.retry.interceptor.StatefulRetryOperationsInterceptor;
+import org.springframework.retry.policy.SimpleRetryPolicy;
+import org.springframework.retry.support.RetryTemplate;
import static org.springframework.amqp.core.Binding.DestinationType.QUEUE
-import org.grails.rabbitmq.RabbitConfigurationHolder
+import org.springframework.amqp.rabbit.config.StatefulRetryOperationsInterceptorFactoryBean
+import org.aopalliance.aop.Advice
+import java.io.ByteArrayOutputStream;
+import org.springframework.amqp.support.converter.SimpleMessageConverter
+import java.io.PrintStream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.amqp.core.AmqpTemplate;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.retry.MessageRecoverer;
+import org.springframework.beans.factory.annotation.Autowired;
class RabbitmqGrailsPlugin {
// the plugin version
@@ -85,7 +101,13 @@ class RabbitmqGrailsPlugin {
}
rabbitTemplate(RabbitTemplate) {
connectionFactory = rabbitMQConnectionFactory
- if (messageConverterBean) messageConverter = ref(messageConverterBean)
+ if (messageConverterBean) {
+ messageConverter = ref(messageConverterBean)
+ } else {
+ def converter = new SimpleMessageConverter()
+ converter.createMessageIds = true
+ messageConverter = converter
+ }
}
adm(RabbitAdmin, rabbitMQConnectionFactory)
rabbitErrorHandler(RabbitErrorHandler)
@@ -158,6 +180,28 @@ class RabbitmqGrailsPlugin {
"grails.rabbit.binding.${binding.exchange}.${binding.queue}"(Binding, binding.queue, QUEUE, binding.exchange, binding.rule, binding.arguments )
}
}
+ rabbitRetryHandler(StatefulRetryOperationsInterceptorFactoryBean) {
+ def retryPolicy = new SimpleRetryPolicy()
+ def maxRetryAttempts = 0
+ if(rabbitmqConfig?.retryPolicy?.containsKey('maxAttempts')) {
+ def maxAttemptsConfigValue = rabbitmqConfig.retryPolicy.maxAttempts
+ if(maxAttemptsConfigValue instanceof Integer) {
+ maxRetryAttempts = maxAttemptsConfigValue
+ } else {
+ log.error "rabbitmq.retryPolicy.maxAttempts [$maxAttemptsConfigValue] of type [${maxAttemptsConfigValue.getClass().getName()}] is not an Integer and will be ignored. The default value of [${maxRetryAttempts}] will be used"
+ }
+ }
+ retryPolicy.maxAttempts = maxRetryAttempts
+
+ def backOffPolicy = new FixedBackOffPolicy()
+ backOffPolicy.backOffPeriod = 5000
+
+ def retryTemplate = new RetryTemplate()
+ retryTemplate.retryPolicy = retryPolicy
+ retryTemplate.backOffPolicy = backOffPolicy
+
+ retryOperations = retryTemplate
+ }
}
}
@@ -175,8 +219,10 @@ class RabbitmqGrailsPlugin {
def doWithApplicationContext = { applicationContext ->
def containerBeans = applicationContext.getBeansOfType(SimpleMessageListenerContainer)
+ applicationContext.rabbitTemplate.messageConverter.createMessageIds = true
containerBeans.each { beanName, bean ->
if(isServiceListener(beanName)) {
+ bean.adviceChain = [applicationContext.rabbitRetryHandler] as Advice[]
// Now that the listener is properly configured, we can start it.
bean.start()
}
1  grails-app/conf/BuildConfig.groovy
View
@@ -27,6 +27,7 @@ grails.project.dependency.resolution = {
'slf4j-log4j12',
'log4j'
}
+ runtime "org.springframework.retry:spring-retry:1.0.0.RELEASE"
}
plugins {
1  src/docs/guide/configuration.gdoc
View
@@ -24,4 +24,5 @@ rabbitmq.connectionfactory.virtualHost | The name of the virtual host to connect
rabbitmq.connectionfactory.channelCacheSize | The connection channel cache size | 10
rabbitmq.concurrentConsumers | The number of concurrent consumers to create per message handler. Raising the number is recommended in order to scale the consumption of messages coming in from a queue. Note that ordering guarantees are lost when multiple consumers are registered. | 1
rabbitmq.disableListening | Disables all service listeners so that they won't receive any messages. | false
+rabbitmq.retryPolicy.maxAttempts | Sets the maximum number of retries for failed message deliveries | 0
{table}
Please sign in to comment.
Something went wrong with that request. Please try again.