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.ib...@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 <ch0...@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 <m...@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 <m...@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(" >>> mrai...@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: cib...@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/