Announcement Announcement Module
Collapse
No announcement yet.
In my example how to handle errors with agregator ? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • elitost
    started a topic In my example how to handle errors with agregator ?

    In my example how to handle errors with agregator ?

    Hello,

    I have some problems to understand and to be able to manage error handling with Spring integration, especially with agregator.

    In the following example, I expose a servlet, send Json in the request content, transform it as object input, parallelize 3 calls (one raise errors), aggregate the results and return a json representation of an account list.

    My XML config :

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:si="http://www.springframework.org/schema/integration"
    	xmlns:int="http://www.springframework.org/schema/integration"
    	xmlns:task="http://www.springframework.org/schema/task"
    	xmlns:int-http="http://www.springframework.org/schema/integration/http"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
    		http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http-2.0.xsd
    		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
    
    	<!--==============-->
    	<!-- Channels     -->
    	<!--==============-->
    	
    	<si:channel id="input" />
    	<si:channel id="transformedInput" datatype="google.il.share.dto.Input"/>
    	<si:channel id="outputAggregator" />
    	<si:channel id="channel2Pivot" />
    	<si:channel id="outputPivot"/>
    	<si:channel id="output" />
    		
    	<int:channel id="channel1">	
    		<int:dispatcher task-executor="executor"/>
    	</int:channel>
    	
    	<int:channel id="channel2" >
    		<int:dispatcher task-executor="executor"/>
    	</int:channel>
    	
    	<int:channel id="channel3" >
    		<int:dispatcher task-executor="executor" />
    	</int:channel>
    		
    	<task:executor id="executor" pool-size="5" keep-alive="5"/>
    
    	<!--==============-->
    	<!-- Gateways     -->
    	<!--==============-->
    	
    	<bean id="inboundGateway" class="google.blank.springintegration.tutorial.http.HttpGateway" >
    		<property name="requestChannel" ref="input" />
    		<property name="replyChannel" ref="outputAggregator" />
    		<property name="requestPayloadType" value="java.lang.String" />
    		<property name="replyTimeout" value="10000"></property>
    <!-- 		<property name="errorChannel" ref="exceptionTransformationChannel"></property> -->
    	</bean>
    	
    <!-- 	<si:channel id="exceptionTransformationChannel" />
    	<int:transformer input-channel="exceptionTransformationChannel"
            ref="exceptionTransformer" method="handleError" output-channel="output"/> -->
        
    	<!--==============-->
    	<!-- Activators   -->
    	<!--==============-->
    	
     	<si:service-activator input-channel="channel1" output-channel="output" ref="serviceFacade1" method="getAccounts" />		
    	<si:service-activator input-channel="channel2" output-channel="outputPivot" ref="serviceFacade1" method="getAccountsBis" />	
     	<si:service-activator input-channel="channel3" output-channel="output" ref="serviceFacade1" method="getAccountsWithFailure" />
    	
    	<!--==============-->
    	<!-- Facades      -->
    	<!--==============-->
    	
    	<bean id="serviceFacade1" class="google.il.impl.ServiceFacadeImpl" />
    
    	<!--==============-->
    	<!-- Transformers -->
    	<!--==============-->
    	<bean id="exceptionTransformer" class="google.blank.springintegration.tutorial.http.ExceptionTransformer" />
    	
    	<int:json-to-object-transformer input-channel="input" output-channel="transformedInput" type="google.il.share.dto.Input" />	
    	
    	<int:transformer id="testTransformer" ref="testTransformerBean" input-channel="outputPivot"
                 method="transform" output-channel="output"/>
    	
    	<bean id="testTransformerBean" class="google.blank.springintegration.tutorial.http.TestTransformer" />
    	
    	<int:transformer id="inputTransformer" ref="inputTransformerBean" input-channel="channel2Pivot"
                 method="transform" output-channel="channel2"/>
    	
    	<bean id="inputTransformerBean" class="google.blank.springintegration.tutorial.http.InputTransformer" />
    
    	<!--==============-->
    	<!-- Routers 	  -->
    	<!--==============-->
    	
    	<int:recipient-list-router id="customRouter" input-channel="transformedInput" apply-sequence="true">
    		<int:recipient channel="channel1" />
    		<int:recipient channel="channel2Pivot" />
    		 <int:recipient channel="channel3" />
    	</int:recipient-list-router>
    
    	<!--==============-->
    	<!-- Aggregators  -->
    	<!--==============-->
    			
    	<int:aggregator input-channel="output" output-channel="outputAggregator" method="aggregate" ref="resultAggregator" 		
    		release-strategy-expression="#root.size() eq 3"/>	
    	
    	<bean id="resultAggregator" class="google.blank.springintegration.tutorial.http.ResultAggregator"/>	
    	
    </beans>
    The serviceFacade1 is called with 3 methods that return List of Accounts. One of those methods raises an exception, like this :

    Code:
    ...
    	@Override
    	public List<AccountDto> getAccountsWithFailure(Input input) throws MyBusinessException {
    		long threadId = Thread.currentThread().getId();
    		System.out.println("getAccountsWithFailure on thread id: "+ threadId + " - " + Thread.currentThread().getName());
    		throw new MyBusinessException("I am the MyBusinessException....huhhuuuu");
    	}
    ...
    When I execute my client, it returns an errors like this :

    Code:
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
    <title>Error 500 google.il.share.facade.MyBusinessException: I am the MyBusinessException....huhhuuuu</title>
    </head>
    <body><h2>HTTP ERROR: 500</h2><pre>google.il.share.facade.MyBusinessException: I am the MyBusinessException....huhhuuuu</pre>
    <p>RequestURI=/inboundGateway</p><h3>Caused by:</h3><pre>org.springframework.integration.MessageHandlingException: google.il.share.facade.MyBusinessException: I am the MyBusinessException....huhhuuuu
    	at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:76)
    	at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:67)
    	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.access$000(UnicastingDispatcher.java:52)
    	at org.springframework.integration.dispatcher.UnicastingDispatcher$1.run(UnicastingDispatcher.java:97)
    	at org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:52)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    	at java.lang.Thread.run(Thread.java:662)
    Caused by: google.il.share.facade.MyBusinessException: I am the MyBusinessException....huhhuuuu
    	at google.il.impl.ServiceFacadeImpl.getAccountsWithFailure(ServiceFacadeImpl.java:64)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:69)
    	at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:110)
    	at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:57)
    	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.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:227)
    	at org.springframework.integration.util.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:127)
    	at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:73)
    	... 10 more
    </pre>
    <h3>Caused by:</h3><pre>google.il.share.facade.MyBusinessException: I am the MyBusinessException....huhhuuuu
    	at google.il.impl.ServiceFacadeImpl.getAccountsWithFailure(ServiceFacadeImpl.java:64)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    ...
    ...
    ...
    I would like to return the aggregation of getAccounts and getAccountsBis even if there is an exception inside getAccountsWithFailure.

    How is it possible ?

    Additionnaly, all advices are welcome because I am newbie with Spring Integration.

    Thx by advance.
    Eric

  • Gary Russell
    replied
    I ran it with Spring Integration 3.0.0.M1 and Spring 3.1.3

    Just tested again with SI 2.2.3.RELEASE.

    Looks like you are using some ancient 2.0.x release...
    spring-integration-http-2.0.xsd
    ... so I tested with 2.0.4 and Spring 3.0.5 and all still worked fine.

    I don't have a simple project, I simply added these files to an existing Spring Integration Sample project.

    I just updated the GIST xml file to include the full file.

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:int="http://www.springframework.org/schema/integration"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:task="http://www.springframework.org/schema/task"
    	xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
    		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
    		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    ...
    If you still can't figure it out, I can make a stand-alone project.

    Leave a comment:


  • elitost
    replied
    Hello,

    I can't run the sample :-(

    With only this junit test that loads the Spring context :

    Code:
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "/sample-context.xml" })
    public class SampleTest {
    	
    
    //	@Autowired
    //	MyGateway gateway;
    	
    	@Test
    	public void test() {
    //		List<String> result = gateway.send("foo");
    //		assertEquals("[out:foo, out:foo]", result.toString());
    //		result = gateway.send("fail1");
    //		assertEquals("[err:fail1, out:fail1]", result.toString());
    //		result = gateway.send("fail2");
    //		assertEquals("[out:fail2, err:fail2]", result.toString());
    //		result = gateway.send("failAll");
    //		assertEquals("[err:failAll, err:failAll]", result.toString());
    	}
    	
    }
    And the Spring XML configuration (with the namespaces added):

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:si="http://www.springframework.org/schema/integration"
    	xmlns:int="http://www.springframework.org/schema/integration"
    	xmlns:task="http://www.springframework.org/schema/task"
    	xmlns:int-http="http://www.springframework.org/schema/integration/http"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
    		http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http-2.0.xsd
    		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
    
    	<int:gateway id="gateway"
    		service-interface="foo.Sample$MyGateway"
    		default-reply-channel="reply"
    		default-request-channel="input"/>
     
    	<int:channel id="reply" />
    	
    	<!-- use a pub-sub channel to insert aggregation headers -->
     
    	<int:publish-subscribe-channel id="input" apply-sequence="true" task-executor="exec" />
     
    	<task:executor id="exec" pool-size="5" />
     
    	<!-- First error-handling gateway -->
    	
    	<int:service-activator ref="service1gw" input-channel="input" output-channel="agg" />
     
    	<int:gateway id="service1gw" default-request-channel="input1" error-channel="ec" />
     
    	<!-- Second error-handling gateway -->
     
    	<int:service-activator ref="service2gw" input-channel="input" output-channel="agg" />
     
    	<int:gateway id="service2gw" default-request-channel="input2" error-channel="ec" />
     
    	<!-- Error flow ("catch" block) -->
    	<int:channel id="ec" />
    	
    	<int:transformer input-channel="ec" ref="foo" method="errorHandler" />
    	
    	<!-- Resequence so we have deterministic results for tests -->
    		
    	<int:resequencer input-channel="agg" output-channel="agg2"/>
     
    	<!-- Aggregates returned results from the error handling gateways -->
     
    	<int:aggregator input-channel="agg2" ref="foo" method="aggregate" output-channel="reply" />
     
    	<int:channel id="input1" />
     
    	<int:channel id="input2" />
     
    	<int:service-activator id="service1" input-channel="input1"
    		 ref="foo" method="service" />
    	
    	<int:service-activator id="service2" input-channel="input2"
    		 ref="foo" method="service" />
     
    	<!-- bean with methods for services and transformer -->
     
    	<bean id="foo" class="foo.Sample"/>
    </beans>

    I obtain this error :

    Code:
    GRAVE: Caught exception while allowing TestExecutionListener [org.springframewor[email protected]1a998c7] to prepare test instance [[email protected]]
    java.lang.IllegalStateException: Failed to load ApplicationContext
    	at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308)
    	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
    	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
    	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:220)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:301)
    	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: java.util.ConcurrentModificationException
    	at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
    	at java.util.AbstractList$Itr.next(AbstractList.java:343)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:559)
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    	at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84)
    	at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
    	at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280)
    	at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304)
    	... 24 more
    My jdk is 1.6.0.23 and Spring 3.0.5.

    Do you have an idea ? Could you provide the full project ?

    Thx by advance.

    Leave a comment:


  • Gary Russell
    replied
    Updated the Gist to improve the test case.

    Leave a comment:


  • Gary Russell
    replied
    OK, I posted a solution in this Gist.

    It's not identical to your scenario but, hopefully, you'll understand how to apply it.

    The bottom line is we have to insert a "try/catch" gateway on each thread in order to be able to handle success or failure on one or more of the threads. The result (or error) returned to each gateway is then forwarded on for aggregation, with the final result going to the original inbound gateway.

    Let me know if you have any questions.
    Last edited by Gary Russell; May 3rd, 2013, 12:33 PM.

    Leave a comment:


  • Gary Russell
    replied
    Well I can get it to work by manipulating the headers and config, but it only works if the failure is the last one to be processed; and I have realized there is a much bigger issue with your design.

    As soon as one of your threads gets an error, the gateway receives that error and sends it to the error-channel; by definition, the gateway no longer is waiting for its reply so, if a second thread throws an exception, that error will be lost and you'll never complete the aggregation.

    I believe you will need to insert an intermediate gateway on each thread so each has its own error handler. I'll mock something up and post it shortly.

    Leave a comment:


  • Gary Russell
    replied
    However, this will cause a problem at the aggregator, because now he won't know which channel to use because he has a choice of 2, and will drop them both because he doesn't know how to reconcile the different headers.

    Stand by...
    Last edited by Gary Russell; May 3rd, 2013, 10:19 AM.

    Leave a comment:


  • Gary Russell
    replied
    Oh - of course!

    Once the error occurs, the gateway is no longer waiting on the replyChannel for the original message, it's now waiting on the replyChannel from the ErrorMessage; so the 21 DTO reply is sent to a channel nobody is waiting on.

    When you copy the headers from failedMessage, you shouldn't copy the replyChannel from the failedMessage.
    Last edited by Gary Russell; May 3rd, 2013, 10:37 AM.

    Leave a comment:


  • elitost
    replied
    With eclipse TCP/IP monitor, when it works I have the following informations :

    The request with the content below
    POST /httpRemoting/getAccounts HTTP/1.1
    Host: localhost:8886
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: fr-fr,fr;q=0.9,de-de;q=0.7,de;q=0.6,en-us;q=0.4,en-gb;q=0.3,en;q=0.1
    Accept-Encoding: gzip, deflate
    DNT: 1
    Connection: keep-alive
    Content-Type: application/json; charset=UTF-8
    Content-Length: 102
    Cookie: LoadBalancer=eqDtNm4UKBsc5ZarA+cVNDCCIyk-; JSESSIONID=17t492r6kjusm
    Pragma: no-cache
    Cache-Control: no-cache

    {"inputString":"ERROR","inputInt":20,"wholeYear":f alse,"byDate":false,"startDate":null,"endDate":nul l}
    The response with the content below

    HTTP/1.1 200 OK
    Set-Cookie: LoadBalancer=eqDtNm4UKBsc5ZarA+cVNDCCIyk-;Path=/
    Content-Type: application/json;charset=UTF-8
    Pragma: no-cache
    Cache-Control: no-cache
    Transfer-Encoding: chunked
    Server: Jetty(6.1.x)

    [{"state":"created","accAmount":-1641119218,"accHolder":"getAccounts on thread id: 17 - executor-1","accNumber":304228,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":-1355771089,"accHolder":"getAccounts on thread id: 17 - executor-1","accNumber":671936,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":1214773831,"accHolder":"getAccounts on thread id: 17 - executor-1","accNumber":100369,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":-1261219646,"accHolder":"getAccounts on thread id: 17 - executor-1","accNumber":296585,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":-1786189229,"accHolder":"getAccounts on thread id: 17 - executor-1","accNumber":75373,"accCurrency":"EUR","confiden tial":"CONFIDENTIAL"},{"state":"created","accAmoun t":-1643335048,"accHolder":"getAccounts on thread id: 17 - executor-1","accNumber":361580,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":349927893,"accHolder":"getAccounts on thread id: 17 - executor-1","accNumber":43807,"accCurrency":"EUR","confiden tial":"CONFIDENTIAL"},{"state":"created","accAmoun t":1377750342,"accHolder":"getAccounts on thread id: 17 - executor-1","accNumber":267444,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":-482126822,"accHolder":"getAccounts on thread id: 17 - executor-1","accNumber":112043,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":-1801492515,"accHolder":"getAccounts on thread id: 17 - executor-1","accNumber":495283,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":2028040078,"accHolder":"getAccountsBis on thread id: 21 - executor-5","accNumber":500451,"accCurrency":"EUR","confide ntial":"TRANSFORMED"},{"state":"created","accAmoun t":1306230895,"accHolder":"getAccountsBis on thread id: 21 - executor-5","accNumber":160424,"accCurrency":"EUR","confide ntial":"TRANSFORMED"},{"state":"created","accAmoun t":1203244186,"accHolder":"getAccountsBis on thread id: 21 - executor-5","accNumber":403355,"accCurrency":"EUR","confide ntial":"TRANSFORMED"},{"state":"created","accAmoun t":-1755597415,"accHolder":"getAccountsBis on thread id: 21 - executor-5","accNumber":552121,"accCurrency":"EUR","confide ntial":"TRANSFORMED"},{"state":"created","accAmoun t":1860364189,"accHolder":"getAccountsBis on thread id: 21 - executor-5","accNumber":733569,"accCurrency":"EUR","confide ntial":"TRANSFORMED"},{"state":"created","accAmoun t":1566743242,"accHolder":"getAccountsBis on thread id: 21 - executor-5","accNumber":167608,"accCurrency":"EUR","confide ntial":"TRANSFORMED"},{"state":"created","accAmoun t":-2032708713,"accHolder":"getAccountsBis on thread id: 21 - executor-5","accNumber":703847,"accCurrency":"EUR","confide ntial":"TRANSFORMED"},{"state":"created","accAmoun t":-610207596,"accHolder":"getAccountsBis on thread id: 21 - executor-5","accNumber":509744,"accCurrency":"EUR","confide ntial":"TRANSFORMED"},{"state":"created","accAmoun t":1061046775,"accHolder":"getAccountsBis on thread id: 21 - executor-5","accNumber":908835,"accCurrency":"EUR","confide ntial":"TRANSFORMED"},{"state":"created","accAmoun t":1410494634,"accHolder":"getAccountsBis on thread id: 21 - executor-5","accNumber":186013,"accCurrency":"EUR","confide ntial":"TRANSFORMED"},{"state":"created","accAmoun t":482517847,"accHolder":"getAccountsWithFailur e on thread id: 19 - executor-3","accNumber":118613,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":-1063717157,"accHolder":"getAccountsWithFailure on thread id: 19 - executor-3","accNumber":802871,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":-1793749373,"accHolder":"getAccountsWithFailure on thread id: 19 - executor-3","accNumber":510550,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":-1054398149,"accHolder":"getAccountsWithFailure on thread id: 19 - executor-3","accNumber":166706,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":-60159480,"accHolder":"getAccountsWithFailure on thread id: 19 - executor-3","accNumber":633542,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":1602619437,"accHolder":"getAccountsWithFailu re on thread id: 19 - executor-3","accNumber":269645,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":-856637213,"accHolder":"getAccountsWithFailure on thread id: 19 - executor-3","accNumber":112254,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":2096172511,"accHolder":"getAccountsWithFailu re on thread id: 19 - executor-3","accNumber":661543,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":536348989,"accHolder":"getAccountsWithFailur e on thread id: 19 - executor-3","accNumber":618092,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"},{"state":"created","accAmou nt":1752608395,"accHolder":"getAccountsWithFailu re on thread id: 19 - executor-3","accNumber":481948,"accCurrency":"EUR","confide ntial":"CONFIDENTIAL"}]

    When it fails I have this, only a request without response :

    POST /httpRemoting/getAccounts HTTP/1.1
    Host: localhost:8886
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: fr-fr,fr;q=0.9,de-de;q=0.7,de;q=0.6,en-us;q=0.4,en-gb;q=0.3,en;q=0.1
    Accept-Encoding: gzip, deflate
    DNT: 1
    Connection: keep-alive
    Content-Type: application/json; charset=UTF-8
    Content-Length: 102
    Cookie: LoadBalancer=eqDtNm4UKBsc5ZarA+cVNDCCIyk-; JSESSIONID=1guvmj8hi3z7a
    Pragma: no-cache
    Cache-Control: no-cache


    {"inputString":"ERROR","inputInt":20,"wholeYear":f alse,"byDate":false,"startDate":null,"endDate":nul l}
    And when I put a breakpoint at the first line off the HttpRequestHandlingMessagingGateway.writeResponse method, it is not reached when I use my use case with exception ( It works when I comment the exception ).

    Other ideas ?

    Leave a comment:


  • Gary Russell
    replied
    No ideas, sorry; like I said the only difference I see is the good test sends a result with 30 DTOs, the bad one has 21.

    Maybe a problem on the client?

    If I were debugging it myself, the next step I'd do is use wireshark (or eclipse's TCP/IP Monitor if the client is on the same host) to examine the TCP packets between the client and server).

    If that shows no data going to the client, I'd then start debugging the message conversion in HttpRequestHandlingMessagingGateway.writeResponse.

    Leave a comment:


  • elitost
    replied
    Strange...

    My exceptionTranformer simply create a new list with on DTOs, it explains the 21 DTOs relased.


    My exceptionTranformer :
    public class ExceptionTransformer {

    public Message handleError(MessageHandlingException input) {

    List<AccountDto> list = new ArrayList<AccountDto>();

    AccountDto accountDto = new AccountDto();
    accountDto.setConfidential("EXCEPTION");
    list.add(accountDto);

    GenericMessage<List<AccountDto>> genericMessage = new GenericMessage<List<AccountDto>>(list);

    MessageBuilder messageBuilder = MessageBuilder.withPayload(list).copyHeaders(input .getFailedMessage().getHeaders()).setHeader("monit oring", new MonitoringContext());

    return messageBuilder.build();
    }

    }
    Now, I don't know why I obtain my results without exception raised and no return on my client with the exception.

    Any ideas ?

    Leave a comment:


  • Gary Russell
    replied
    And when I comment the exception sent...

    Right; and the only difference in the second log is the line "postSend (sent=true) on channel 'outputAggregator" contains 30 DTOs instead of 21.

    Leave a comment:


  • Gary Russell
    replied
    I don't know your application or what your "exceptionTransformer" is doing but what I see in the log is an error at line 194; this is transformed to what looks like a single AccountDTO which is sent to the aggregator, which releases the group, containing 21 AccountDTOs (line 213); this is sent as a reply to the gateway.

    At line 159 I see a payload with 10 DTOs arriving at the aggregator (sequenceNumber=1, sequenceSize=3); the next 10 arrive at line 199 (sequenceNumber2) and the single (failed) DTO arrives at line 206 and the 21 DTOs are released.

    This looks like a single list so it looks like your 'resultsAggregator' merges the lists in the 3 payloads.

    So it all looks fine to me.

    Leave a comment:


  • elitost
    replied
    And when I comment the exception sent, I receive my results and you can see the DEBUG log in attachments looking differently.

    Leave a comment:


  • elitost
    replied
    :-) On my side it is not really obvious, this is the logs with DEBUG activated joined to the message.

    Maybe more clear for you ?

    Leave a comment:

Working...
X