camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matt Raible <m...@raibledesigns.com>
Subject Re: Email Error on Route Exception
Date Fri, 23 May 2014 14:27:24 GMT
That worked - thanks!

.setHeader("subject", simple("Message Broker Error ({{ESB_ENV}}) - ${exception.class.simpleName}"))
.transform(simple("${exception.message}\n\nStacktrace Details:\n\n${exception.stacktrace}"))
.to("freemarker:/templates/mail/error.ftl")
.to("smtp://{{mail.host}}?contentType=text/plain&to={{ESB_ALERT_EMAIL}}" +
		"&from={{mail.from}}&subject=${headers.subject})");

On May 23, 2014, at 8:08 AM, Claus Ibsen <claus.ibsen@gmail.com> wrote:

> You can set the subject as a header, then the smtp will use that
> 
> Something like this (not wrote the code in this email)
> .setHeader("subject", simple("Message Broker Error
> ${exception.getClassName()}"))
> 
> On Fri, May 23, 2014 at 3:45 PM, Matt Raible <matt@raibledesigns.com> wrote:
>> I was able to figure out how to set headers and retrieve those variables in the FreeMarker
template. However, I'm still unable to access them in the SMTP endpoint. Also, if I set the
"exception", I can't call ${exception.stacktrace} in FreeMarker like I can in a simple transform.
Here's what I have now.
>> 
>> .setHeader("routeId", property(Exchange.FAILURE_ROUTE_ID))
>> .setHeader("endpoint", property(Exchange.FAILURE_ENDPOINT))
>> .setHeader("exception", property(Exchange.EXCEPTION_CAUGHT))
>> .transform(simple("${exception.message}\n\nStacktrace Details:\n\n${exception.stacktrace}"))
>> .to("freemarker:/templates/mail/error.ftl")
>> .to("smtp://{{mail.host}}?contentType=text/plain&to={{ESB_ALERT_EMAIL}}" +
>>                "&from={{mail.from}}&subject=Message Broker Error ({{ESB_ENV}}
- ${exception.className})");
>> 
>> The main thing I'd like to change is to send the Exception class name in the subject.
Currently, it prints:
>> 
>> Message Broker Error (mraible - ${exception.className})
>> 
>> On May 23, 2014, at 12:53 AM, Claus Ibsen <claus.ibsen@gmail.com> wrote:
>> 
>>> Hi
>>> 
>>> Yeah a good idea is to check the unit tests for camel-freemarker for examples.
>>> 
>>> Also take a note that Camel stores various information from the
>>> Exchange etc. and provides that to freemarker in the process method.
>>> https://github.com/apache/camel/blob/master/components/camel-freemarker/src/main/java/org/apache/camel/component/freemarker/FreemarkerEndpoint.java#L122
>>> 
>>> eg that is what we say on the page, at the section _freemarker context_
>>> http://camel.apache.org/freemarker
>>> 
>>> So I would assume you can use the freemarker syntax to access those
>>> and retrieve the caused exception, headers, and what else you need.
>>> 
>>> On Fri, May 23, 2014 at 8:21 AM, Charles Moulliard <ch007m@gmail.com> wrote:
>>>> Matt,
>>>> 
>>>> You ca retrieve using ${body} and ${headers.xxxx} within the freemarker
>>>> template (
>>>> https://github.com/apache/camel/blob/master/components/camel-freemarker/src/test/resources/org/apache/camel/component/freemarker/letterWithoutHeader.ftl#L21)
>>>> the content of your body or headers/properties like also fields of an
>>>> object (
>>>> https://github.com/apache/camel/blob/master/components/camel-freemarker/src/test/resources/org/apache/camel/component/freemarker/BodyAsDomainObject.ftl#L19
>>>> ).
>>>> 
>>>> Have you try this syntax --> ${headers.operationName} ?
>>>> 
>>>> Regards,
>>>> 
>>>> Charles
>>>> 
>>>> 
>>>> On Thu, May 22, 2014 at 10:12 PM, Matt Raible <matt@raibledesigns.com>wrote:
>>>> 
>>>>> I figured out a solution for this. First of all, I changed my route to
be
>>>>> a Spring bean so dependency injection would work:
>>>>> 
>>>>> @Component
>>>>> public class FooRoute extends RouteBuilder {
>>>>> }
>>>>> 
>>>>> Then I changed my Camel configuration to use Spring annotations and
>>>>> @ComponentScan. I also configured things so properties from my Spring
>>>>> property placeholder would be available to Camel.
>>>>> 
>>>>> @Configuration
>>>>> @ImportResource("classpath:META-INF/cxf/cxf.xml")
>>>>> @ComponentScan("com.foo.app")
>>>>> public class CamelConfig extends CamelConfiguration {
>>>>> 
>>>>>       @Override
>>>>>       protected void setupCamelContext(CamelContext camelContext) throws
>>>>> Exception {
>>>>>               PropertiesComponent pc = new PropertiesComponent();
>>>>>               pc.setLocation("classpath:application.properties");
>>>>>               camelContext.addComponent("properties", pc);
>>>>>               super.setupCamelContext(camelContext);
>>>>>       }
>>>>> }
>>>>> 
>>>>> That was enough to solve the problem below. However, I figured I'd take
it
>>>>> a step further and use Camel to send the email instead of my own Spring
>>>>> bean.
>>>>> 
>>>>>               onException(Exception.class)
>>>>>                               .transform(simple("There was a problem
due
>>>>> ${exception.message} and the \n" +
>>>>>                                               "stracktrace is
>>>>> ${exception.stacktrace}"))
>>>>> 
>>>>> .to("smtp://{{mail.host}}?contentType=text/plain&to={{mail.to}}"
+
>>>>> 
>>>>> "&from={{mail.from}}&subject=Message Broker Error");
>>>>> 
>>>>> This worked, until I wanted to add a corporate disclaimer in the footer.
>>>>> For this, I turned to FreeMarker. It seems I still need the transform
if I
>>>>> want to get the stacktrace as I was unable to get it from the exception
in
>>>>> FreeMarker.
>>>>> 
>>>>>               onException(Exception.class)
>>>>> 
>>>>> .transform(simple("${exception.stacktrace}"))
>>>>>                               .to("freemarker:/error.ftl")
>>>>> 
>>>>> .to("smtp://{{mail.host}}?contentType=text/plain&to={{ESB_ALERT_EMAIL}}"
+
>>>>> 
>>>>> "&from={{mail.from}}&subject=Message Broker Error ({{ESB_ENV}})");
>>>>> 
>>>>> In error.ftl, I have:
>>>>> 
>>>>> ----
>>>>> <#assign exception = exchange.properties.CamelExceptionCaught>
>>>>> ${exception.message}
>>>>> 
>>>>> Stacktrace Details:
>>>>> 
>>>>> ${body}
>>>>> 
>>>>> For full trace of input message and exceptions, please check the Message
>>>>> Broker Logs.
>>>>> 
>>>>> IMPORTANT CONFIDENTIALITY NOTICE
>>>>> 
>>>>> Lots of corporate legal-eze here.
>>>>> ----
>>>>> 
>>>>> The only thing I'd like to know now is if it's possible to get the
>>>>> serviceName and operationName to put in the subject. I tried
>>>>> ${header.operationName}, but it just prints the raw value. The application
>>>>> I'm trying to replace had a number of system properties included in the
>>>>> email as well, so I'd be interested in knowing how to include those in
the
>>>>> FreeMarker template too.
>>>>> 
>>>>> Thanks,
>>>>> 
>>>>> Matt
>>>>> 
>>>>> On May 22, 2014, at 9:41 AM, Matt Raible <matt@raibledesigns.com>
wrote:
>>>>> 
>>>>>> Hello all,
>>>>>> 
>>>>>> I'm getting up to speed on Apache Camel and trying to replace a "message
>>>>> flow" that was originally written for IBM Message Broker 6.1. The flow
>>>>> involves receiving input from a SOAP service, looking up a value in a
>>>>> database, and returning that to the client (again, via SOAP). I have
a
>>>>> route that works and now I'm trying to add exception handling to it.
>>>>> Ideally, an email can be generated when an exception occurs.
>>>>>> 
>>>>>> Here's my Route:
>>>>>> 
>>>>>> public class FooRoute extends RouteBuilder {
>>>>>> 
>>>>>>     private String uri = "cxf:/foo?serviceClass=" +
>>>>> FooService.class.getName();
>>>>>> 
>>>>>>     private Log log = LogFactory.getLog(FooRoute.class);
>>>>>> 
>>>>>>     @Autowired
>>>>>>     private MailSender mailSender;
>>>>>> 
>>>>>>     @Autowired
>>>>>>     private SimpleMailMessage mailMessage;
>>>>>> 
>>>>>>     @Override
>>>>>>     public void configure() throws Exception {
>>>>>>             onException(Exception.class)
>>>>>>                             .process(new Processor() {
>>>>>>                                     public void process(Exchange
>>>>> exchange) throws Exception {
>>>>>>                                             Exception exception =
>>>>> (Exception) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
>>>>>>                                             // email error
>>>>>>                                             mailMessage.setTo("
>>>>> mraible@apache.org");
>>>>>> 
>>>>> mailMessage.setSubject("ERROR!!");
>>>>>> 
>>>>> mailMessage.setText("WTF?!\n\n " + exception.getMessage());
>>>>>> 
>>>>> mailSender.send(mailMessage);
>>>>>>                                     }
>>>>>>                             });
>>>>>>             from(uri)
>>>>>>                             .to("log:input")
>>>>>>                                             // send the request to
the
>>>>> route to handle the operation
>>>>>>                                             // the name of the
>>>>> operation is in that header
>>>>>> 
>>>>> .recipientList(simple("direct:${header.operationName}"));
>>>>>>             from("direct:findById")
>>>>>>                             .process(new Processor() {
>>>>>>                                     public void process(Exchange
>>>>> exchange) throws Exception {
>>>>>>                                             // get the id from the
>>>>> input
>>>>>>                                             String id =
>>>>> exchange.getIn().getBody(FooRequest.class).getId();
>>>>>> 
>>>>> exchange.getOut().setBody(id);
>>>>>>                                     }
>>>>>>                             })
>>>>>>                             .to("sql:select value from table where
id
>>>>> = #?dataSource=ds")
>>>>>>                             .to("log:output")
>>>>>>                             .process(new Processor() {
>>>>>>                                     public void process(Exchange
>>>>> exchange) throws Exception {
>>>>>>                                             // get the value from
the
>>>>> input
>>>>>>                                             List<HashMap> data
=
>>>>> (ArrayList<HashMap>) exchange.getIn().getBody();
>>>>>>                                             // todo: handle value
is
>>>>> empty
>>>>>>                                             FooResponse response
= new
>>>>> FooResponse();
>>>>>> 
>>>>> response.setGpi(String.valueOf(data.get(0).get("value")));
>>>>>> 
>>>>> exchange.getOut().setBody(response);
>>>>>>                                     }
>>>>>>                             }).end();
>>>>>>     }
>>>>>> }
>>>>>> 
>>>>>> The problem that I'm experiencing is that the Autowired dependencies
>>>>> from Spring are not getting set. Do I need to do something special to
allow
>>>>> Spring dependencies in my route or is there an easier way to send exception
>>>>> emails?
>>>>>> 
>>>>>> Here's how I have my routes configured using Spring's JavaConfig:
>>>>>> 
>>>>>> @Configuration
>>>>>> @ImportResource("classpath:META-INF/cxf/cxf.xml")
>>>>>> public class CamelConfig extends CamelConfiguration implements
>>>>> InitializingBean {
>>>>>> 
>>>>>>     /**
>>>>>>      * Returns the CamelContext which support Spring
>>>>>>      */
>>>>>>     @Override
>>>>>>     protected CamelContext createCamelContext() throws Exception
{
>>>>>>             return new SpringCamelContext(getApplicationContext());
>>>>>>     }
>>>>>> 
>>>>>>     @Override
>>>>>>     public List<RouteBuilder> routes() {
>>>>>>             List<RouteBuilder> routes = new ArrayList<>();
>>>>>>             routes.add(new FooRoute());
>>>>>>             return routes;
>>>>>>     }
>>>>>> 
>>>>>>     public void afterPropertiesSet() throws Exception {}
>>>>>> }
>>>>>> 
>>>>>> Thanks,
>>>>>> 
>>>>>> Matt
>>>>> 
>>>>> 
>>>> 
>>>> 
>>>> --
>>>> Charles Moulliard
>>>> Apache Committer / Architect @RedHat
>>>> Twitter : @cmoulliard | Blog :  http://cmoulliard.github.io
>>> 
>>> 
>>> 
>>> --
>>> Claus Ibsen
>>> -----------------
>>> Red Hat, Inc.
>>> Email: cibsen@redhat.com
>>> Twitter: davsclaus
>>> Blog: http://davsclaus.com
>>> Author of Camel in Action: http://www.manning.com/ibsen
>>> hawtio: http://hawt.io/
>>> fabric8: http://fabric8.io/
>> 
> 
> 
> 
> -- 
> Claus Ibsen
> -----------------
> Red Hat, Inc.
> Email: cibsen@redhat.com
> Twitter: davsclaus
> Blog: http://davsclaus.com
> Author of Camel in Action: http://www.manning.com/ibsen
> hawtio: http://hawt.io/
> fabric8: http://fabric8.io/


Mime
View raw message