CAMEL-9929: Fix camel-restlet - Using synchronous=false with no error handler leak inflight exchange
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/e4dbb8e3 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/e4dbb8e3 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/e4dbb8e3 Branch: refs/heads/camel-2.17.x Commit: e4dbb8e37dca20c8754fe0b0f2792cfa8db2c3cc Parents: 9d7824b Author: Claus Ibsen <davscl...@apache.org> Authored: Fri Apr 29 14:10:40 2016 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Fri Apr 29 14:12:19 2016 +0200 ---------------------------------------------------------------------- .../component/restlet/RestletProducer.java | 7 +- .../RecipientListInflightExchangesTest.java | 83 ++++++++++++++++++++ 2 files changed, 87 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/e4dbb8e3/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletProducer.java b/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletProducer.java index 5e94a64..6d53fa5 100644 --- a/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletProducer.java +++ b/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletProducer.java @@ -96,9 +96,10 @@ public class RestletProducer extends DefaultAsyncProducer { if (endpoint.isSynchronous()) { try { process(exchange); - } catch (Exception e) { + } catch (Throwable e) { exchange.setException(e); } + callback.done(true); return true; } @@ -110,7 +111,7 @@ public class RestletProducer extends DefaultAsyncProducer { String resourceUri = buildUri(endpoint, exchange); request = new Request(endpoint.getRestletMethod(), resourceUri); binding.populateRestletRequestFromExchange(request, exchange); - } catch (CamelExchangeException e) { + } catch (Throwable e) { // break out in case of exception exchange.setException(e); callback.done(true); @@ -132,7 +133,7 @@ public class RestletProducer extends DefaultAsyncProducer { binding.populateExchangeFromRestletResponse(exchange, response); } } - } catch (Exception e) { + } catch (Throwable e) { exchange.setException(e); } finally { callback.done(false); http://git-wip-us.apache.org/repos/asf/camel/blob/e4dbb8e3/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RecipientListInflightExchangesTest.java ---------------------------------------------------------------------- diff --git a/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RecipientListInflightExchangesTest.java b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RecipientListInflightExchangesTest.java new file mode 100644 index 0000000..6449016 --- /dev/null +++ b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RecipientListInflightExchangesTest.java @@ -0,0 +1,83 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.restlet; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.junit.Test; + +public class RecipientListInflightExchangesTest extends RestletTestSupport { + + @Test + public void testRecipientListWithBean() throws Exception { + // there should be 0 inflight when we start + assertEquals(0, context.getInflightRepository().size()); + + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedBodiesReceived("RS-response", "RS-response"); + + String out = template.requestBody("direct:start", "theBody", String.class); + assertEquals("RS-response", out); + + //invoke twice + out = template.requestBody("direct:start", "theBody", String.class); + assertEquals("RS-response", out); + + assertMockEndpointsSatisfied(); + + // and there should be 0 inflight when we are finished + assertEquals(0, context.getInflightRepository().size()); + } + + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + context.setStreamCaching(true); + + // turn off error handler + errorHandler(noErrorHandler()); + + //route under test + from("direct:start").routeId("test1") + .process(new MyInflightCheckBean()) + .recipientList().simple("restlet:http://localhost:" + portNum + "/users/123/basic?synchronous=true") + .to("mock:result"); + + // restlet "Server" side + from("restlet:http://localhost:" + portNum + "/users/{id}/basic") + .process(new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getOut().setBody("RS-response"); + } + }); + } + }; + } + + public class MyInflightCheckBean implements Processor { + + @Override + public void process(Exchange exchange) throws Exception { + // there should only be one exchange in flight at the time this bean is invoked. + assertEquals("Should not be more than 1 exchanges inflight", 1, exchange.getContext().getInflightRepository().size()); + } + } + +} \ No newline at end of file