Grokbase Groups Camel users July 2013
FAQ
I find Camel easy for difficult use cases but hard to simple use cases. Or
maybe I haven't still mastered it.

I have a JAX-RS web service that when executed, will dynamically create a
route that reads mail from an IMAP server and then gets processed via a
bean.

My problem is that I need to add Thread.sleep(10000); so that the web
service waits until the route completes.

My issue is I want a better way to know if the route has completed instead
of setting some arbitrary timer that has the potential for side effects.
(e.g. waiting unnecessarily when the route might have already finished or
even worse existing before the route has time to complete it's work.

I am wondering how others might have done something similar to this
requirement? Any ideas/suggestions are welcome as I have done everything
possible including reading other posts in this forum, looking at the camel
source code and test code without much success.

My main code is below (note I have a JEE6 bootstrap class that starts
CamelContext and which in turn is injected into the below jax-rs service)

@Path("/Mail")
public class ReadMail {

  private static final Logger logger = LoggerFactory
    .getLogger(ReadMail.class);

     @Inject
     CdiCamelContext camelContext;

  @Path("/read")
  @GET
  @Produces(MediaType.TEXT_HTML)
  public Response getUser(@Context UriInfo uriInfo) {

   try {

    logger.debug(">>> Reading mail from mail server ..");
    MultivaluedMap<String, String> queryParameters = uriInfo
      .getQueryParameters();
    String mailProtocol =
queryParameters.getFirst("mailProtocol").toLowerCase();
    String mailHost = queryParameters.getFirst("host").toLowerCase();
    String userName = queryParameters.getFirst("username");
    String password = queryParameters.getFirst("password");

    final String MAIL_ENDPOINT_URI = mailProtocol + "://" + mailHost
      + "?username="+ userName + "&password=" + password + "&delete=false"
      + "&debugMode=true&unseen=true&consumer.delay=5000";

    final MailBean mailBean = new MailBean();

    camelContext.addRoutes(new RouteBuilder() {
     public void configure() throws Exception {
      from(MAIL_ENDPOINT_URI).routeId("myRoute")
      .bean(mailBean, "processMail");
     }
    });

    Thread.sleep(10000);

    return
Response.status(Response.Status.OK).entity(mailBean.getMessageBody().toString())
      .build();

   } catch (Exception e) {
    e.printStackTrace();
   }
   finally {
    try {
     camelContext.stopRoute("myRoute");
     camelContext.removeRoute("myRoute");
    } catch (Exception e) {
     e.printStackTrace();
    }
   }

   return Response.status(Response.Status.NOT_FOUND)
     .entity("Requested search did not return any results").build();

  }

}

My Bean class is

public class MailBean {

  private StringBuilder messageBody = new StringBuilder();

  public void processMail(Exchange exchange) throws MessagingException,
IOException {

                 System.out.println(">>>> Inside MailBean exchangeTest >>>>
");
                 System.out.println("<<<< Message Id:"+
exchange.getIn().getMessageId());

         this.setMessageBody(this.getMessageBody().append("Message Id:"+
exchange.getIn().getMessageId()+ "<br/><br/>"));

         if (exchange.getIn().getBody() instanceof String) {

          this.setMessageBody(this.getMessageBody().append(((String)
exchange.getIn().getBody()).replaceAll("(\r\n|\n)", "")+ "<br/><br/>"));

         } else if (exchange.getIn().getBody() instanceof Multipart) {


this.setMessageBody(this.getMessageBody().append((Utility.getMultipartText((Multipart)
exchange.getIn().getBody())).replaceAll("(\r\n|\n)","")+ "<br/><br/>"));

         }
  }

  public StringBuilder getMessageBody() {
   return messageBody;
  }
  public void setMessageBody(StringBuilder messageBody) {
   this.messageBody = messageBody;
  }

}





--
View this message in context: http://camel.465427.n5.nabble.com/Camel-Consumer-in-JAX-RS-Web-Service-tp5735968.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Search Discussions

  • Sergey Beryozkin at Jul 21, 2013 at 7:34 pm
    Can you add a final component to that mail route which will simply
    notify this ReadMail resource that the route is done ?

    Sergey
    On 21/07/13 17:16, traviskds wrote:
    I find Camel easy for difficult use cases but hard to simple use cases. Or
    maybe I haven't still mastered it.

    I have a JAX-RS web service that when executed, will dynamically create a
    route that reads mail from an IMAP server and then gets processed via a
    bean.

    My problem is that I need to add Thread.sleep(10000); so that the web
    service waits until the route completes.

    My issue is I want a better way to know if the route has completed instead
    of setting some arbitrary timer that has the potential for side effects.
    (e.g. waiting unnecessarily when the route might have already finished or
    even worse existing before the route has time to complete it's work.

    I am wondering how others might have done something similar to this
    requirement? Any ideas/suggestions are welcome as I have done everything
    possible including reading other posts in this forum, looking at the camel
    source code and test code without much success.

    My main code is below (note I have a JEE6 bootstrap class that starts
    CamelContext and which in turn is injected into the below jax-rs service)

    @Path("/Mail")
    public class ReadMail {

    private static final Logger logger = LoggerFactory
    .getLogger(ReadMail.class);

    @Inject
    CdiCamelContext camelContext;

    @Path("/read")
    @GET
    @Produces(MediaType.TEXT_HTML)
    public Response getUser(@Context UriInfo uriInfo) {

    try {

    logger.debug(">>> Reading mail from mail server ..");
    MultivaluedMap<String, String> queryParameters = uriInfo
    .getQueryParameters();
    String mailProtocol =
    queryParameters.getFirst("mailProtocol").toLowerCase();
    String mailHost = queryParameters.getFirst("host").toLowerCase();
    String userName = queryParameters.getFirst("username");
    String password = queryParameters.getFirst("password");

    final String MAIL_ENDPOINT_URI = mailProtocol + "://" + mailHost
    + "?username="+ userName + "&password=" + password + "&delete=false"
    + "&debugMode=true&unseen=true&consumer.delay=5000";

    final MailBean mailBean = new MailBean();

    camelContext.addRoutes(new RouteBuilder() {
    public void configure() throws Exception {
    from(MAIL_ENDPOINT_URI).routeId("myRoute")
    .bean(mailBean, "processMail");
    }
    });

    Thread.sleep(10000);

    return
    Response.status(Response.Status.OK).entity(mailBean.getMessageBody().toString())
    .build();

    } catch (Exception e) {
    e.printStackTrace();
    }
    finally {
    try {
    camelContext.stopRoute("myRoute");
    camelContext.removeRoute("myRoute");
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    return Response.status(Response.Status.NOT_FOUND)
    .entity("Requested search did not return any results").build();

    }

    }

    My Bean class is

    public class MailBean {

    private StringBuilder messageBody = new StringBuilder();

    public void processMail(Exchange exchange) throws MessagingException,
    IOException {

    System.out.println(">>>> Inside MailBean exchangeTest >>>>
    ");
    System.out.println("<<<< Message Id:"+
    exchange.getIn().getMessageId());

    this.setMessageBody(this.getMessageBody().append("Message Id:"+
    exchange.getIn().getMessageId()+ "<br/><br/>"));

    if (exchange.getIn().getBody() instanceof String) {

    this.setMessageBody(this.getMessageBody().append(((String)
    exchange.getIn().getBody()).replaceAll("(\r\n|\n)", "")+ "<br/><br/>"));

    } else if (exchange.getIn().getBody() instanceof Multipart) {


    this.setMessageBody(this.getMessageBody().append((Utility.getMultipartText((Multipart)
    exchange.getIn().getBody())).replaceAll("(\r\n|\n)","")+ "<br/><br/>"));

    }
    }

    public StringBuilder getMessageBody() {
    return messageBody;
    }
    public void setMessageBody(StringBuilder messageBody) {
    this.messageBody = messageBody;
    }

    }





    --
    View this message in context: http://camel.465427.n5.nabble.com/Camel-Consumer-in-JAX-RS-Web-Service-tp5735968.html
    Sent from the Camel - Users mailing list archive at Nabble.com.
  • Traviskds at Jul 22, 2013 at 12:01 pm
    Thanks for responding Sergey.

    I assume you mean adding the "to" part of the route.

    I did this

        camelContext.addRoutes(new RouteBuilder() {
         public void configure() throws Exception {
          from(MAIL_ENDPOINT_URI).routeId("myRoute")
          .bean(mailBean, "processMail")
          .to("log:mail");
         }
        });

    and no impact. Then I did this

        camelContext.addRoutes(new RouteBuilder() {
         public void configure() throws Exception {
          from(MAIL_ENDPOINT_URI).routeId("myRoute")
          .to("bean:mailBean?method=processMail");
         }
        });

    and no impact. Note I registered the bean using SimpleRegistry before adding
    it to the route in the 2nd set of code.

    But in both instances, and even in my original code when I have
    Thread.sleep(10000); it works.

    I am really stuck at this point as what I plan to do is provide JAX-RS
    services as an API Gateway and use Camel for various backend integration and
    if I cannot have Synchronous calls in JAX-RS, it is a show stopper for my
    use cases.

    In the Camel In Action book, in page 97-98, Service Activator Pattern, I was
    under the impression when the BeanProcessor is used, then it will make a
    Synchronous call.

    I think maybe I am not understanding this correctly.

    Any help is appreciated.






    --
    View this message in context: http://camel.465427.n5.nabble.com/Camel-Consumer-in-JAX-RS-Web-Service-tp5735968p5736023.html
    Sent from the Camel - Users mailing list archive at Nabble.com.
  • Sergey Beryozkin at Jul 22, 2013 at 12:33 pm
    I've been thinking more along these lines:

    class ReadMail {

          public Response read(...) {

             MailBean bean = new MailBean();
             new Thread().run(new MyRouteWrapper(bean));
             // block on the current thread
             bean.waitTillDone();



          }

          private MyRouteWrapper implements Runnable {
              // here goes your mail route
              // the last part of this route will call a MailBean method
    which will unblock a waiting readMail thread

          }
    }

    Something like that...

    Cheers, Sergey
    On 22/07/13 13:00, traviskds wrote:
    Thanks for responding Sergey.

    I assume you mean adding the "to" part of the route.

    I did this

    camelContext.addRoutes(new RouteBuilder() {
    public void configure() throws Exception {
    from(MAIL_ENDPOINT_URI).routeId("myRoute")
    .bean(mailBean, "processMail")
    .to("log:mail");
    }
    });

    and no impact. Then I did this

    camelContext.addRoutes(new RouteBuilder() {
    public void configure() throws Exception {
    from(MAIL_ENDPOINT_URI).routeId("myRoute")
    .to("bean:mailBean?method=processMail");
    }
    });

    and no impact. Note I registered the bean using SimpleRegistry before adding
    it to the route in the 2nd set of code.

    But in both instances, and even in my original code when I have
    Thread.sleep(10000); it works.

    I am really stuck at this point as what I plan to do is provide JAX-RS
    services as an API Gateway and use Camel for various backend integration and
    if I cannot have Synchronous calls in JAX-RS, it is a show stopper for my
    use cases.

    In the Camel In Action book, in page 97-98, Service Activator Pattern, I was
    under the impression when the BeanProcessor is used, then it will make a
    Synchronous call.

    I think maybe I am not understanding this correctly.

    Any help is appreciated.






    --
    View this message in context: http://camel.465427.n5.nabble.com/Camel-Consumer-in-JAX-RS-Web-Service-tp5735968p5736023.html
    Sent from the Camel - Users mailing list archive at Nabble.com.

    --
    Sergey Beryozkin

    Talend Community Coders
    http://coders.talend.com/

    Blog: http://sberyozkin.blogspot.com
  • Claus Ibsen at Jul 22, 2013 at 1:00 pm
    You can look at using onCompletion or event notifier. Or even the NotifyBuilder.

    You can find details on the Camel site using the search box on the front page.
    On Sun, Jul 21, 2013 at 6:16 PM, traviskds wrote:
    I find Camel easy for difficult use cases but hard to simple use cases. Or
    maybe I haven't still mastered it.

    I have a JAX-RS web service that when executed, will dynamically create a
    route that reads mail from an IMAP server and then gets processed via a
    bean.

    My problem is that I need to add Thread.sleep(10000); so that the web
    service waits until the route completes.

    My issue is I want a better way to know if the route has completed instead
    of setting some arbitrary timer that has the potential for side effects.
    (e.g. waiting unnecessarily when the route might have already finished or
    even worse existing before the route has time to complete it's work.

    I am wondering how others might have done something similar to this
    requirement? Any ideas/suggestions are welcome as I have done everything
    possible including reading other posts in this forum, looking at the camel
    source code and test code without much success.

    My main code is below (note I have a JEE6 bootstrap class that starts
    CamelContext and which in turn is injected into the below jax-rs service)

    @Path("/Mail")
    public class ReadMail {

    private static final Logger logger = LoggerFactory
    .getLogger(ReadMail.class);

    @Inject
    CdiCamelContext camelContext;

    @Path("/read")
    @GET
    @Produces(MediaType.TEXT_HTML)
    public Response getUser(@Context UriInfo uriInfo) {

    try {

    logger.debug(">>> Reading mail from mail server ..");
    MultivaluedMap<String, String> queryParameters = uriInfo
    .getQueryParameters();
    String mailProtocol =
    queryParameters.getFirst("mailProtocol").toLowerCase();
    String mailHost = queryParameters.getFirst("host").toLowerCase();
    String userName = queryParameters.getFirst("username");
    String password = queryParameters.getFirst("password");

    final String MAIL_ENDPOINT_URI = mailProtocol + "://" + mailHost
    + "?username="+ userName + "&password=" + password + "&delete=false"
    + "&debugMode=true&unseen=true&consumer.delay=5000";

    final MailBean mailBean = new MailBean();

    camelContext.addRoutes(new RouteBuilder() {
    public void configure() throws Exception {
    from(MAIL_ENDPOINT_URI).routeId("myRoute")
    .bean(mailBean, "processMail");
    }
    });

    Thread.sleep(10000);

    return
    Response.status(Response.Status.OK).entity(mailBean.getMessageBody().toString())
    .build();

    } catch (Exception e) {
    e.printStackTrace();
    }
    finally {
    try {
    camelContext.stopRoute("myRoute");
    camelContext.removeRoute("myRoute");
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    return Response.status(Response.Status.NOT_FOUND)
    .entity("Requested search did not return any results").build();

    }

    }

    My Bean class is

    public class MailBean {

    private StringBuilder messageBody = new StringBuilder();

    public void processMail(Exchange exchange) throws MessagingException,
    IOException {

    System.out.println(">>>> Inside MailBean exchangeTest >>>>
    ");
    System.out.println("<<<< Message Id:"+
    exchange.getIn().getMessageId());

    this.setMessageBody(this.getMessageBody().append("Message Id:"+
    exchange.getIn().getMessageId()+ "<br/><br/>"));

    if (exchange.getIn().getBody() instanceof String) {

    this.setMessageBody(this.getMessageBody().append(((String)
    exchange.getIn().getBody()).replaceAll("(\r\n|\n)", "")+ "<br/><br/>"));

    } else if (exchange.getIn().getBody() instanceof Multipart) {


    this.setMessageBody(this.getMessageBody().append((Utility.getMultipartText((Multipart)
    exchange.getIn().getBody())).replaceAll("(\r\n|\n)","")+ "<br/><br/>"));

    }
    }

    public StringBuilder getMessageBody() {
    return messageBody;
    }
    public void setMessageBody(StringBuilder messageBody) {
    this.messageBody = messageBody;
    }

    }





    --
    View this message in context: http://camel.465427.n5.nabble.com/Camel-Consumer-in-JAX-RS-Web-Service-tp5735968.html
    Sent from the Camel - Users mailing list archive at Nabble.com.


    --
    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
  • Traviskds at Jul 24, 2013 at 9:59 am
    Thanks Sergey and Claus.

    Using both of your suggestions (i.e. running the routes in a new thread and
    using the onCompletion, I was able to get it to work, sort of :(

    What I notice is that the onCompletion does not fire after all the mails are
    received, but after 2-3 mails. (it is not consistent)

    This made me think a little bit about routes and if it works per email
    message.

    If that is the case, then I may need to use an aggregator strategy. I am
    going to try that now but do you think I am on the correct path and my
    understanding on routes being one message at a time correct?

    Sorry if these are dumb questions as I am on this Camel learning curve (or
    should I say trying to ride the Camel)



    --
    View this message in context: http://camel.465427.n5.nabble.com/Camel-Consumer-in-JAX-RS-Web-Service-tp5735968p5736190.html
    Sent from the Camel - Users mailing list archive at Nabble.com.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupusers @
categoriescamel
postedJul 21, '13 at 4:17p
activeJul 24, '13 at 9:59a
posts6
users3
websitecamel.apache.org

People

Translate

site design / logo © 2022 Grokbase