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/