1

Разбираюсь с apache camel и в частности с ErrorHandler.

<errorHandler id="deadError" type="DeadLetterChannel" deadLetterUri="file:data/fault" useOriginalMessage="true"/>
<errorHandler id="logError" type="LoggingErrorHandler" level="WARN"/>
<errorHandler id="noError" type="NoErrorHandler"/>
<dataFormats>
 <jaxb id="jaxb" contextPath="ru.camel"/>
</dataFormats>
<route id="requestRoute" errorHandlerRef="noError">
 <from uri="file:data/input"/>
 <unmarshal ref="jaxb"/>
 <process ref="WsCaller"/>
 <to uri="direct:startSoap"/>
 <marshal ref="jaxb"/>
 <convertBodyTo type="String"/>
 <log message="FileName=${in.header.fileName}"/>
 <to uri="file:data/output?fileName=${in.header.fileName}"/>
</route>
<route id="soapRoute" errorHandlerRef="noError" handleFault="true">
 <from uri="direct:startSoap"/>
 <log message="Вызов метода ${in.header.operationName}"/>
 <setHeader headerName="operationName">
 <constant>calcSumm</constant>
 </setHeader>
 <to uri="cxf:bean:externalWS"/>
 <process ref="WsResult"/>
</route>

Из каталога data/input читается файл содержащий данные которые будут использоваться для вызова Web-сервиса (простой веб сервис складывающий два числа). Ответ Web-сервиса разбирается и в конце формируется файл с ответом в каталоге data/input.

Когда я выключаю web-сервис при его вызове возникает Exception:

org.apache.cxf.interceptor.Fault: Could not send Message.
 at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64)
 at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
 at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
 at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:416)
 at org.apache.camel.component.cxf.CxfProducer.process(CxfProducer.java:120)
 at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145)
 at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
 at org.apache.camel.processor.interceptor.HandleFaultInterceptor.process(HandleFaultInterceptor.java:42)
 at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:91)
 at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:91)
 at org.apache.camel.builder.NoErrorHandlerBuilder1ドル.process(NoErrorHandlerBuilder.java:40)
 at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
 at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
 at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
 at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
 at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62)
 at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145)
 at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
 at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:91)
 at org.apache.camel.builder.NoErrorHandlerBuilder1ドル.process(NoErrorHandlerBuilder.java:40)
 at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
 at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
 at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
 at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
 at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:454)
 at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:226)
 at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:190)
 at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:175)
 at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:102)
 at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
 at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
 at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access301ドル(ScheduledThreadPoolExecutor.java:180)
 at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
 at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.ConnectException: ConnectException invoking http://air-aleksej:8080/SimpleWebService/Calculate: Connection refused (Connection refused)
 at sun.reflect.GeneratedConstructorAccessor57.newInstance(Unknown Source)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
 at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1377)
 at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1361)
 at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
 at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:651)
 at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
 ... 35 more 

Исходный файл остается в каталоге и route уходит в бесконечный цикл.

Как с помощью onErrorHandler можно обойти данную ситуацию. Т.е. я хочу отключить реакцию на недоступный web-сервис, чтобы Camel не регировал на возникшую ошибку и завершал route. Т.е. чтобы исходный файл удалялся.

Как я понимаю noErrorHandle позволяет это сделать, но либо я неправильно понимаю его смысл, или что-то делаю не так.

Mikhail Grebenev
1,3087 серебряных знаков19 бронзовых знаков
задан 9 мая 2018 в 16:08

1 ответ 1

1

Полезные ссылки с офф.сайта:

  1. Error handling in Camel
  2. Try ... Catch ... Finally

То, что route уходит в бесконечный цикл - это в принципе правильно, конечная цель же не достигнута. Можно сделать разные варианты по реализации (действия по обработке Exception или try-catch-finaly). Например, удаление файла можно сделать в finally.

В итоге, предлагаю обернуть вызов web-service в try-catch. И в случае exception выполнить некие действия с файлом в catch.

Примеры в статьях:

  1. On the road to Camel 2.0 - Try Catch Finally
  2. Try, Catch, Finally with Camel

Вариант структуры route в Java DSL:

from("direct:start")
 .doTry()
 .process(new ProcessorFail())
 .to("mock:result")
 .doCatch(IOException.class, IllegalStateException.class)
 .to("mock:catch")
 .doFinally()
 .to("mock:finally")
 .end();

Вариант структуры route в XML:

<route>
 <from uri="direct:start"/>
 <!-- here the try starts. its a try .. catch .. finally just as regular java code -->
 <doTry>
 <process ref="processorFail"/>
 <to uri="mock:result"/>
 <doCatch>
 <!-- catch multiple exceptions -->
 <exception>java.io.IOException</exception>
 <exception>java.lang.IllegalStateException</exception>
 <to uri="mock:catch"/>
 </doCatch>
 <doFinally>
 <to uri="mock:finally"/>
 </doFinally>
 </doTry>
</route>

Дополняю ответ по вопросу: для чего нужен NoErrorHandler?

Ссылка на офф.описание с примером: Error Handler

NoErrorHandler - используется для отключения обработчиков ошибок и не более того. Но это не исключает возникновение Exception со всеми вытекающими последствиями.

Применительно к текущему вопросу, когда требуется удалять файл в любом случае, NoErrorHandler не применим.

Где применять NoErrorHandler и зачем он вообще нужен?

Как пишут, это некий 'dummy-error-handler', когда разработчик хочет забить на все ошибки и в своем no-transacted маршруте не хочет их обрабатывать по какой-то причине.

Как делать правильно или "NoErrorHandler must die".

Стандартный подход - это реализовать обработчик ошибок по требуемому набору Exceptions. Примерно так:

onException(ConnectException.class)
 .bean(MyProcessorForFileDelete())
 .handled(true);
ответ дан 9 мая 2018 в 16:53
2
  • Спасибо за ответ, суть моего вопроса скорее не в том как достигнуть цель иными путями, а понять суть NoErrorHandler, для чего он и как и когда его применять. Commented 9 мая 2018 в 16:58
  • @Алексей, я дополнил ответ про NoErrorHandler, надеюсь поможет. Commented 10 мая 2018 в 9:52

Ваш ответ

Черновик сохранён
Черновик удалён

Зарегистрируйтесь или войдите

Регистрация через Google
Регистрация через почту

Отправить без регистрации

Необходима, но никому не показывается

Отправить без регистрации

Необходима, но никому не показывается

Нажимая «Отправить ответ», вы соглашаетесь с условиями пользования и подтверждаете, что прочитали политику конфиденциальности.

Начните задавать вопросы и получать на них ответы

Найдите ответ на свой вопрос, задав его.

Задать вопрос

Изучите связанные вопросы

Посмотрите похожие вопросы с этими метками.