Add a DataFormat programatically

2017-01-01 Thread Robert Huffman
I'm having trouble adding the ProtobufDataFormat to a route. I have
ActiveMQ BytesMessages whose bodies are Protobuf messages.

The documentation (http://camel.apache.org/protobuf.html) certainly looks
straightforward, so here's what I have:

ProtobufDataFormat protobufFormat = new ProtobufDataFormat();
context.addRoutes(new RouteBuilder() {
  public void configure() throws Exception {
from("jms:queue:test)
.unmarshal(protobufFormat)
.process((exchange) -> {...});

But this gives me an exception:

Caused by: java.lang.IllegalArgumentException: Data format 'protobuf' could
not be created. Ensure that the data format is valid and the associated
Camel component is present on the classpath
at
org.apache.camel.model.DataFormatDefinition.getDataFormat(DataFormatDefinition.java:107)
at
org.apache.camel.model.DataFormatDefinition.getDataFormat(DataFormatDefinition.java:88)
at
org.apache.camel.model.MarshalDefinition.createProcessor(MarshalDefinition.java:177)
at
org.apache.camel.model.ProcessorDefinition.makeProcessorImpl(ProcessorDefinition.java:545)
at
org.apache.camel.model.ProcessorDefinition.makeProcessor(ProcessorDefinition.java:506)
at
org.apache.camel.model.ProcessorDefinition.addRoutes(ProcessorDefinition.java:222)
at
org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1068)
... 42 more


Any ideas?

Also, is there a way to programatically add the ProtobufDataDefinition to
the CamelContext when I create it so I can use it in routes without
instantiating it? (I tried adding it as a serivce, registering it in the
registry, and adding it to the context's data format map, and I always got
the same exception as the one above.)


Handling errors

2017-01-03 Thread Robert Huffman
I'm having trouble understanding how to write and use an error handler. The
use case is testing a custom Camel component. I would like to have an error
handler that just collects any exceptions thrown by the endpoint's producer.

I somewhat naively assumed this would be simple. I thought the Camel
framework must catch any exception, add it the exchange, and invoke the
handler's process method. That appears not to be the case.

Below is my attempt. The test is set up so my the producer will throw an
exception. To my surprise, the CaptureErrorHandler.process method is being
invoked twice. my component's producer is never invoked.

But If I remove usage of my my error handler from the RouteBuilder, the
producer is invoked, and it throws an exception that is logged by the
DefaultErrorHandler.

Clearly, I don't understand how error handles are supposed to be used. Can
someone enlighten me, or point me to more detailed documentation? The Camel
documentation for ErrorHandler is pretty light on details. Alternatively,
maybe there's a simpler approach I can take for testing my component.


The RouteBuilder's configure method looks like this:

public void configure() throws Exception {
  errorHandler(new CaptureErrorHandlerBuilder());
  from(destinations)
  .process(new Counter())
  .to("foo:endpoint");
}


And the CaptureErrorHandlerBuilder and CaptureErrorHandler looks like this:

private class CaptureErrorHandlerBuilder extends ErrorHandlerBuilderSupport
{

  @Override
  public boolean supportTransacted() {
return false;
  }

  @Override
  public ErrorHandlerBuilder cloneBuilder() {
return new CaptureErrorHandlerBuilder();
  }

  @Override
  public Processor createErrorHandler(RouteContext routeContext, Processor
processor) throws Exception {
CaptureErrorHandler handler = new CaptureErrorHandler();
configure(routeContext, handler);
return handler;
  }
}

private class CaptureErrorHandler implements ErrorHandler {
  @Override
  public void process(Exchange exchange) throws Exception {
Exception e = exchange.getException();

// For now, just log the exception

if (e != null) {
  e.printStackTrace();

}

  }
}


Re: Handling errors

2017-01-03 Thread Robert Huffman
Well, of course I read that, but all I want is access to the actual
Exception objects in my test. I can add the try/catch clauses, but as
nearly as I can tell the only thing you can do with the catch is route to
another endpoint. Isn't there a simple way to get at the underlying
exceptions?


On Tue, Jan 3, 2017 at 10:57 AM, Claus Ibsen  wrote:

> Hi
>
> You should not build your own, but use what is OOTB
> http://camel.apache.org/error-handling-in-camel.html
>
> If you have Camel in Action book then it has a full chapter devoted to
> error handling.
>
>
>
> On Tue, Jan 3, 2017 at 7:44 PM, Robert Huffman 
> wrote:
> > I'm having trouble understanding how to write and use an error handler.
> The
> > use case is testing a custom Camel component. I would like to have an
> error
> > handler that just collects any exceptions thrown by the endpoint's
> producer.
> >
> > I somewhat naively assumed this would be simple. I thought the Camel
> > framework must catch any exception, add it the exchange, and invoke the
> > handler's process method. That appears not to be the case.
> >
> > Below is my attempt. The test is set up so my the producer will throw an
> > exception. To my surprise, the CaptureErrorHandler.process method is
> being
> > invoked twice. my component's producer is never invoked.
> >
> > But If I remove usage of my my error handler from the RouteBuilder, the
> > producer is invoked, and it throws an exception that is logged by the
> > DefaultErrorHandler.
> >
> > Clearly, I don't understand how error handles are supposed to be used.
> Can
> > someone enlighten me, or point me to more detailed documentation? The
> Camel
> > documentation for ErrorHandler is pretty light on details. Alternatively,
> > maybe there's a simpler approach I can take for testing my component.
> >
> >
> > The RouteBuilder's configure method looks like this:
> >
> > public void configure() throws Exception {
> >   errorHandler(new CaptureErrorHandlerBuilder());
> >   from(destinations)
> >   .process(new Counter())
> >   .to("foo:endpoint");
> > }
> >
> >
> > And the CaptureErrorHandlerBuilder and CaptureErrorHandler looks like
> this:
> >
> > private class CaptureErrorHandlerBuilder extends
> ErrorHandlerBuilderSupport
> > {
> >
> >   @Override
> >   public boolean supportTransacted() {
> > return false;
> >   }
> >
> >   @Override
> >   public ErrorHandlerBuilder cloneBuilder() {
> > return new CaptureErrorHandlerBuilder();
> >   }
> >
> >   @Override
> >   public Processor createErrorHandler(RouteContext routeContext,
> Processor
> > processor) throws Exception {
> > CaptureErrorHandler handler = new CaptureErrorHandler();
> > configure(routeContext, handler);
> > return handler;
> >   }
> > }
> >
> > private class CaptureErrorHandler implements ErrorHandler {
> >   @Override
> >   public void process(Exchange exchange) throws Exception {
> > Exception e = exchange.getException();
> >
> > // For now, just log the exception
> >
> > if (e != null) {
> >   e.printStackTrace();
> >
> > }
> >
> >   }
> > }
>
>
>
> --
> Claus Ibsen
> -
> http://davsclaus.com @davsclaus
> Camel in Action 2: https://www.manning.com/ibsen2
>


Re: Handling errors

2017-01-03 Thread Robert Huffman
Ah, nice. I did not see that. Thanks for pointing it out. (And I'll check
out that chapter, too.)


On Tue, Jan 3, 2017 at 1:15 PM, Claus Ibsen  wrote:

> Hi
>
> There is this FAQ
> http://camel.apache.org/why-is-the-exception-null-when-i-
> use-onexception.html
>
> On Tue, Jan 3, 2017 at 9:31 PM, Robert Huffman 
> wrote:
> > Well, of course I read that, but all I want is access to the actual
> > Exception objects in my test. I can add the try/catch clauses, but as
> > nearly as I can tell the only thing you can do with the catch is route to
> > another endpoint. Isn't there a simple way to get at the underlying
> > exceptions?
> >
> >
> > On Tue, Jan 3, 2017 at 10:57 AM, Claus Ibsen 
> wrote:
> >
> >> Hi
> >>
> >> You should not build your own, but use what is OOTB
> >> http://camel.apache.org/error-handling-in-camel.html
> >>
> >> If you have Camel in Action book then it has a full chapter devoted to
> >> error handling.
> >>
> >>
> >>
> >> On Tue, Jan 3, 2017 at 7:44 PM, Robert Huffman <
> robert.huff...@gmail.com>
> >> wrote:
> >> > I'm having trouble understanding how to write and use an error
> handler.
> >> The
> >> > use case is testing a custom Camel component. I would like to have an
> >> error
> >> > handler that just collects any exceptions thrown by the endpoint's
> >> producer.
> >> >
> >> > I somewhat naively assumed this would be simple. I thought the Camel
> >> > framework must catch any exception, add it the exchange, and invoke
> the
> >> > handler's process method. That appears not to be the case.
> >> >
> >> > Below is my attempt. The test is set up so my the producer will throw
> an
> >> > exception. To my surprise, the CaptureErrorHandler.process method is
> >> being
> >> > invoked twice. my component's producer is never invoked.
> >> >
> >> > But If I remove usage of my my error handler from the RouteBuilder,
> the
> >> > producer is invoked, and it throws an exception that is logged by the
> >> > DefaultErrorHandler.
> >> >
> >> > Clearly, I don't understand how error handles are supposed to be used.
> >> Can
> >> > someone enlighten me, or point me to more detailed documentation? The
> >> Camel
> >> > documentation for ErrorHandler is pretty light on details.
> Alternatively,
> >> > maybe there's a simpler approach I can take for testing my component.
> >> >
> >> >
> >> > The RouteBuilder's configure method looks like this:
> >> >
> >> > public void configure() throws Exception {
> >> >   errorHandler(new CaptureErrorHandlerBuilder());
> >> >   from(destinations)
> >> >   .process(new Counter())
> >> >   .to("foo:endpoint");
> >> > }
> >> >
> >> >
> >> > And the CaptureErrorHandlerBuilder and CaptureErrorHandler looks like
> >> this:
> >> >
> >> > private class CaptureErrorHandlerBuilder extends
> >> ErrorHandlerBuilderSupport
> >> > {
> >> >
> >> >   @Override
> >> >   public boolean supportTransacted() {
> >> > return false;
> >> >   }
> >> >
> >> >   @Override
> >> >   public ErrorHandlerBuilder cloneBuilder() {
> >> > return new CaptureErrorHandlerBuilder();
> >> >   }
> >> >
> >> >   @Override
> >> >   public Processor createErrorHandler(RouteContext routeContext,
> >> Processor
> >> > processor) throws Exception {
> >> > CaptureErrorHandler handler = new CaptureErrorHandler();
> >> > configure(routeContext, handler);
> >> > return handler;
> >> >   }
> >> > }
> >> >
> >> > private class CaptureErrorHandler implements ErrorHandler {
> >> >   @Override
> >> >   public void process(Exchange exchange) throws Exception {
> >> > Exception e = exchange.getException();
> >> >
> >> > // For now, just log the exception
> >> >
> >> > if (e != null) {
> >> >   e.printStackTrace();
> >> >
> >> > }
> >> >
> >> >   }
> >> > }
> >>
> >>
> >>
> >> --
> >> Claus Ibsen
> >> -
> >> http://davsclaus.com @davsclaus
> >> Camel in Action 2: https://www.manning.com/ibsen2
> >>
>
>
>
> --
> Claus Ibsen
> -
> http://davsclaus.com @davsclaus
> Camel in Action 2: https://www.manning.com/ibsen2
>


Re: Handling errors

2017-01-03 Thread Robert Huffman
To close this discussion, Claus's solution, along with try, catch and
process, clauses, worked for me.


The route looks like this:

from(destinations)
.doTry()
.to("foo:bar")
.doCatch(Exception.class)
.process((exchange) -> handleException(exchange));


And the method to add the exception to a collection looks like this:

private void handleException(Exchange exchange) {
  Exception e = exchange.getException();
  if (e == null) {
// If another handler marked the exception as handled, we have to get
the
// original exception from a property.
// See
http://camel.apache.org/why-is-the-exception-null-when-i-use-onexception.html
e = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
  }
  if (e != null) {
exceptions.add(e);
  }
}


Thanks for the help.

On Tue, Jan 3, 2017 at 2:31 PM, Robert Huffman 
wrote:

> Ah, nice. I did not see that. Thanks for pointing it out. (And I'll check
> out that chapter, too.)
>
>
> On Tue, Jan 3, 2017 at 1:15 PM, Claus Ibsen  wrote:
>
>> Hi
>>
>> There is this FAQ
>> http://camel.apache.org/why-is-the-exception-null-when-i-use
>> -onexception.html
>>
>> On Tue, Jan 3, 2017 at 9:31 PM, Robert Huffman 
>> wrote:
>> > Well, of course I read that, but all I want is access to the actual
>> > Exception objects in my test. I can add the try/catch clauses, but as
>> > nearly as I can tell the only thing you can do with the catch is route
>> to
>> > another endpoint. Isn't there a simple way to get at the underlying
>> > exceptions?
>> >
>> >
>> > On Tue, Jan 3, 2017 at 10:57 AM, Claus Ibsen 
>> wrote:
>> >
>> >> Hi
>> >>
>> >> You should not build your own, but use what is OOTB
>> >> http://camel.apache.org/error-handling-in-camel.html
>> >>
>> >> If you have Camel in Action book then it has a full chapter devoted to
>> >> error handling.
>> >>
>> >>
>> >>
>> >> On Tue, Jan 3, 2017 at 7:44 PM, Robert Huffman <
>> robert.huff...@gmail.com>
>> >> wrote:
>> >> > I'm having trouble understanding how to write and use an error
>> handler.
>> >> The
>> >> > use case is testing a custom Camel component. I would like to have an
>> >> error
>> >> > handler that just collects any exceptions thrown by the endpoint's
>> >> producer.
>> >> >
>> >> > I somewhat naively assumed this would be simple. I thought the Camel
>> >> > framework must catch any exception, add it the exchange, and invoke
>> the
>> >> > handler's process method. That appears not to be the case.
>> >> >
>> >> > Below is my attempt. The test is set up so my the producer will
>> throw an
>> >> > exception. To my surprise, the CaptureErrorHandler.process method is
>> >> being
>> >> > invoked twice. my component's producer is never invoked.
>> >> >
>> >> > But If I remove usage of my my error handler from the RouteBuilder,
>> the
>> >> > producer is invoked, and it throws an exception that is logged by the
>> >> > DefaultErrorHandler.
>> >> >
>> >> > Clearly, I don't understand how error handles are supposed to be
>> used.
>> >> Can
>> >> > someone enlighten me, or point me to more detailed documentation? The
>> >> Camel
>> >> > documentation for ErrorHandler is pretty light on details.
>> Alternatively,
>> >> > maybe there's a simpler approach I can take for testing my component.
>> >> >
>> >> >
>> >> > The RouteBuilder's configure method looks like this:
>> >> >
>> >> > public void configure() throws Exception {
>> >> >   errorHandler(new CaptureErrorHandlerBuilder());
>> >> >   from(destinations)
>> >> >   .process(new Counter())
>> >> >   .to("foo:endpoint");
>> >> > }
>> >> >
>> >> >
>> >> > And the CaptureErrorHandlerBuilder and CaptureErrorHandler looks like
>> >> this:
>> >> >
>> >> > private class CaptureErrorHandlerBuilder extends
>> >> ErrorHandlerBuilderSupport
>> >> > {
>> >> >
>> >> >   @Override
>> >> >   public boolean supportTransacted() {
>> >> >