Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Two advice in one request-handler-advice-chain

  1. #1

    Default Two advice in one request-handler-advice-chain

    Hello,
    first of all thank you for developing request-handler-advice-chain.

    I have simply question. Is there possible to have combination of RequestHandlerRetryAdvice and ExpressionEvaluatingRequestHandlerAdvice in one request-handler-advice-chain?

    I would like to do 3 tries for some action (like for ftp otbound like in the following code) - in case of success invoke success-expression and in case of 3 failed tries invoke on error-expression but it seems to me that this configuration is doing only one try (in case of error) and then ExpressionEvaluatingRequestHandlerAdvice action (error-expression).

    Code:
    <int-ftp:outbound-channel-adapter id="ftpOutbound"
    		channel="ftpOutChannel"
    		session-factory="ftpOUT"
    		remote-directory="/foo"
    		<int-ftp:request-handler-advice-chain >
    			<bean id="retyrAdvice" class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
    				<property name="retryTemplate">
    					<bean class="org.springframework.retry.support.RetryTemplate">
    						<property name="backOffPolicy">
    							<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
    								<property name="initialInterval" value="5000" />
    								<property name="multiplier" value="3" />
    							</bean>
    						</property>
    					</bean>
    				</property>
    			</bean>
    			<bean id="errorHandler" class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice" >
    				<property name="trapException" value="true"></property>
    				<property name="onSuccessExpression" value="payload.delete()" />
    				<property name="successChannel" ref="afterSuccessDeleteChannel" />
    				<property name="onFailureExpression" value="payload.renameTo(new java.io.File('/foo/failed/' + payload.getName() + '.failed'))" />
    				<property name="failureChannel" ref="afterFailRenameChannel" />
    			</bean>
    		</int-ftp:request-handler-advice-chain>
    	</int-ftp:outbound-channel-adapter>
    Thank you,
    Jakub

  2. #2
    Join Date
    Jan 2009
    Location
    Ukraine, Kharkov
    Posts
    640

    Default

    Hello, Jakub!

    Yes, it is: we already observed it and fixed: https://jira.springsource.org/browse/INT-2858.
    So, just get the latest 2.2.1.SNAPSHOT and have a good time!

    Take care,
    Artem

  3. #3

    Default

    Thank you :-),
    I have switched to 2.2.1.BUILD-SNAPSHOT and it works. Interesting note is that it works (3 attempts) only in case of definition in such order:
    Code:
    <int-ftp:request-handler-advice-chain >
       <bean id="errorHandler" class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice"/>   
       <bean id="retyrAdvice" class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice"/>
    </int-ftp:request-handler-advice-chain>
    for this one:
    Code:
    <int-ftp:request-handler-advice-chain >
       <bean id="retyrAdvice" class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice"/>
       <bean id="errorHandler" class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice"/>
    </int-ftp:request-handler-advice-chain>
    there are logged always only two tries <Retry: count=0>,<Retry: count=1> and then it goes to ExpressionEvaluatingRequestHandlerAdvice (even if I use 5 attempts in retryPolicy)

    ---------------------------------------------------------------------------------------------------
    I have also one question regarding Error message which is sent to failureChannel. Please let me know whether I should create new thread for this.

    Lets say that this ftp outbound action fails due to non-exsting target path. Without spring-integration or without ExpressionEvaluatingRequestHandlerAdvice I get full stack trace with many "causes" and root cause
    java.io.IOException: Failed to write.... Server replied with: 553 Could not create file. which is quite important information.

    In my failureChannel where I use following expression I get following message:
    Code:
    expression="payload.getMessage()+' cause: '+payload.getCause()"
    
    Handler Failed cause: org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice$ThrowableHolderException: org.springframework.integration.MessagingException: Failed to invoke handler
    which has only final Exception + cause. Is there somehow possible to get root cause? BTW payload.getCause().getStackTrace().toString() did not help.

    Thank you,
    Jakub

  4. #4
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,029

    Default

    The advices are nested (chained); I am surprised to see any retries when the error handler (with trapException="true") is defined AFTER the retry advice. I'll run some tests.

    The exception should be in payload.cause.cause - but I don't think we should be exposing the ThrowableHolderException, we should be unwrapping it - again, I'll run some tests to see what's going on.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  5. #5
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,029

    Default

    I just ran some tests and it worked as expected for me; when the chain was defined with the retry advice first, and the errorHandler second (with trapException = true) I only see one attempt (count=0) because, from the perspective of the retry advice, the downstream calls were successful (the errorHandler trapped the exception).

    When I put the errorHandler first, I see the 3 attempts followed by the error going to the 'afterFailRenameChannel'.

    However, we should not be leaking the ThrowableHolderException to the outside world. I opened a new JIRA for that. https://jira.springsource.org/browse/INT-2894
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  6. #6

    Default

    Thank you Gary,
    you are right - I saw <Retry: count=0>,<Retry: count=1> (when the error handler is defined AFTER the retry advice) event when trapException="false".
    --------------------------------------------------------
    Also thank you for opening of JIRA regarding Exceptions - I am trying 2.2.1-RELEASE now and payload.cause.cause.cause.cause returns the root cause . However - is there any way how to get it directly - without nesting (since for some other type exceptions the value of expression: payload.cause.cause.cause.cause does not need to exist and it will throw Expression evaluation failed)

    Regards,
    Jakub

  7. #7
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,029

    Default

    2.2.1 should be suppressing the ThrowableHolderException; can you post a full stack trace?
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  8. #8

    Default

    this is what I am doing:
    Code:
    	<int:header-enricher input-channel="afterFailRenameChannel" output-channel="logChannel">
    		<int:header name="LEVEL" value="ERROR"/>
    		<int:header name="TITLE" value="FILE NOT_TRANSFERED"/>
    		<int:header name="MESSAGE" expression="'Moving of ' + payload.failedMessage.payload.absolutePath + ' to ${integration.ftp.failed.location} after failed transfer, result: '+payload.getMessage()+' cause: '+payload.cause.cause.cause.cause"/>
    	</int:header-enricher>
    payload.cause.cause.cause.cause - returns
    Code:
    java.io.IOException: Failed to write to ''/apps/soadev/ftp/inbound/platform_spring_test/write/somefile-20130128113542.dat.writing''. Server replied with: 553 Could not create file
    which is good - this is what I want but the problem is that other type of error can has different number of causes so it can returns null or throws exception like in the following:
    payload.cause.cause.cause.cause.cause - returns null
    payload.cause.cause.cause.cause.cause.cause - returns (this is reasonable since the parent cause is null)

  9. #9

    Default

    exception is too long - I am not able to send full stackTrace

    Code:
    Caused by: org.springframework.integration.MessagingException: failed to transform message headers
    	at org.springframework.integration.transformer.HeaderEnricher.transform(HeaderEnricher.java:122)
    	at org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:67)
    	... 120 more
    Caused by: org.springframework.integration.MessageHandlingException: Expression evaluation failed: 'Moving of ' + payload.failedMessage.payload.absolutePath + ' to d:/temp/failed after failed transfer, result: '+payload.getMessage()+' cause: '+payload.cause.cause.cause.cause.cause.cause
    	at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:93)
    	at org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor.processMessage(ExpressionEvaluatingMessageProcessor.java:67)
    	at org.springframework.integration.transformer.HeaderEnricher$ExpressionEvaluatingHeaderValueMessageProcessor.processMessage(HeaderEnricher.java:216)
    	at org.springframework.integration.transformer.HeaderEnricher.transform(HeaderEnricher.java:113)
    	... 121 more
    Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1007E:(pos 183): Field or property 'cause' cannot be found on null
    	at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:205)
    	at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:72)
    	at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:57)
    	at org.springframework.expression.spel.ast.OpPlus.getValueInternal(OpPlus.java:63)
    	at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:102)
    	at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:102)
    	at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:126)
    	at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:86)
    	... 124 more

  10. #10

    Default

    this is the begining
    Code:
    org.springframework.integration.transformer.MessageTransformationException: org.springframework.integration.MessagingException: failed to transform message headers
    	at org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:73)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:134)
    	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:115)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:102)
    	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
    	at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
    	at org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice.evaluateFailureExpression(ExpressionEvaluatingRequestHandlerAdvice.java:169)
    	at org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice.doInvoke(ExpressionEvaluatingRequestHandlerAdvice.java:125)
    	at org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice.invoke(AbstractRequestHandlerAdvice.java:58)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    	at $Proxy18.handleMessage(Unknown Source)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:115)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:102)
    	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
    	at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(AbstractReplyProducingMessageHandler.java:216)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(AbstractReplyProducingMessageHandler.java:200)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(AbstractReplyProducingMessageHandler.java:165)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:159)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:141)
    	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:115)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:102)
    	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
    	at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(AbstractReplyProducingMessageHandler.java:216)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(AbstractReplyProducingMessageHandler.java:200)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(AbstractReplyProducingMessageHandler.java:165)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:155)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:141)
    	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:115)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:102)
    	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
    	at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(AbstractReplyProducingMessageHandler.java:216)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(AbstractReplyProducingMessageHandler.java:200)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(AbstractReplyProducingMessageHandler.java:165)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:159)
    	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:141)
    	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
    	at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:121)
    	at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:112)
    	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •