1

I have three camel routes running fine individually, I am trying to call second route once first route is complete, but some how it is not being initiated how event third route is running once I call second route using URL jetty:http://localhost:8181/mongoSelect , I have no error on the console as well. I have already tried changing from("jetty:http://localhost:8181/mongoSelect") with direct: component, Please help me on this.

Constants

private static final String SOURCE = "file:\\workspace\\EmailResponseAutomationSTS\\response\\?noop=true";
private static final String DESTINATION = "mongodb:myDb?database=email_response&collection=emailResponse&operation=save";
private static final String QUERY_MONGO_DB = "mongodb:myDb?database=email_response&collection=emailResponse&operation=findAll";

First Route

from(SOURCE)
        .process(new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                final EmailResponseModel erm = new EmailResponseModel();
                erm.setBody(exchange.getIn().getBody(String.class));
                exchange.getIn().setBody(erm, DBObject.class);
            }
        })
        .to(DESTINATION)
        .end();

Second Route

from("jetty:http://localhost:8181/mongoSelect")
        .to(QUERY_MONGO_DB)
        .marshal(new JacksonDataFormat())
        .to("direct:redis")
        .end();

Third Route

from("direct:redis").process(new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {

                final String name = exchange.getIn().getBody(String.class);
                @SuppressWarnings({ "deprecation", "unchecked" })
                List<BasicDBObject> obj = (List<BasicDBObject>) JSON.parse(name);

                for(BasicDBObject model : obj) {
                    String s = model.getString("body");
                    jedis.set("mongoData", s); 
                }
                jedis.close();
            }
        })
        .end();

I have already tried this approach:

First Route

from(SOURCE)
        .process(new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                final EmailResponseModel erm = new EmailResponseModel();
                erm.setBody(exchange.getIn().getBody(String.class));
                exchange.getIn().setBody(erm, DBObject.class);
            }
        })
        .to(DESTINATION)
        .to("direct:mongoSelect")
        .end();

Second Route

from("direct:mongoSelect")
.to(QUERY_MONGO_DB)
.marshal(new JacksonDataFormat())
.to("direct:redis")
.end();

UPDATE : Something strange is happening with my code, when I am calling second route from first route using direct:mongoSelect component, control is moving in but there is no data in response from .to(QUERY_MONGO_DB), however if I am using from("jetty:http://localhost:8181/mongoSelect") instead of from("direct:mongoSelect") in second route, I am getting data in response.

First Route

from(SOURCE)
        .process(new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                final EmailResponseModel erm = new EmailResponseModel();
                erm.setEmailBody(exchange.getIn().getBody(String.class));
                exchange.getIn().setBody(erm, DBObject.class);
            }
        })
        .to(DESTINATION)
        .to("direct:mongoSelect");

Second Route

from("direct:mongoSelect")
        .to(QUERY_MONGO_DB)
        .process(new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                String srt = exchange.getIn().getBody(String.class);
                exchange.getIn().setBody(srt, DBObject.class);
            }
        })
        .to("direct:redis")
        .end();
Shamim Ahmad
  • 808
  • 3
  • 22
  • 40

2 Answers2

1

Try this. This should work.

from(SOURCE)
        .process(new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                final EmailResponseModel erm = new EmailResponseModel();
                erm.setBody(exchange.getIn().getBody(String.class));
                exchange.getIn().setBody(erm, DBObject.class);
            }
        })
        .to(DESTINATION)
        .to("direct:mongoSelect")
        .end();
Second Route

from("direct:mongoSelect")
        .setHeader(Exchange.HTTP_METHOD, constant("GET")) // Change it based on HTTP method type
        .setHeader("Content-Type",simple("application/json"))
        .setHeader("Accept", simple("application/json"))  
        .to("jetty:http://localhost:8181/mongoSelect")
        .to(QUERY_MONGO_DB)
        .marshal(new JacksonDataFormat())
        .to("direct:redis")
        .end();
pvpkiran
  • 25,582
  • 8
  • 87
  • 134
  • Got this exception on console `org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: com.mongodb.WriteResult to the required type: java.io.InputStream with value WriteResult{n=0, updateOfExisting=false, upsertedId=null}` – Shamim Ahmad Mar 27 '18 at 09:51
  • This has something to do with data type conversion. You need to take care of it. Is the route getting called now? – pvpkiran Mar 27 '18 at 09:53
  • Yes, it is being called but, I don't want to use `jetty:http://localhost:8181/mongoSelect` since all three routes are in the same class. Isn't a way to call using some component like `direct:` – Shamim Ahmad Mar 27 '18 at 09:55
  • don't understand what you are asking – pvpkiran Mar 27 '18 at 10:04
  • I mean, I don't want to use rest-api call to access second route. Is there any other way to access it, like `direct:` component is used for control transfer. – Shamim Ahmad Mar 27 '18 at 10:56
  • you are not accessing second route through rest-api, you are accessing through `direct:mongoselect` – pvpkiran Mar 27 '18 at 13:07
1

You seem to be stuck, here some suggestions to go forward.

  • Your first route reads from a file and writes to mongo-db
  • Initially, it did not call the second route

If it is a requirement that the second route is a HTTP service that listens at http://localhost:8181/mongoSelect and your first route should call it, the first route has to call the same URL.

.to(DESTINATION) => Mongo-DB write
.to("[call to http://localhost:8181/mongoSelect]")
.end();

However, if it does not need to be a HTTP service, the endpoint direct:mongoSelect should work fine, as @pvpkiran suggested. But then you have other problems:

  • You write that you get no mongodb-results if you use direct:mongoSelect. That is probably because the message body from the first route is still there and therefore used as query string for mongodb.
  • Set your message body correct with .setBody() before you read from the database

If the mongodb-query in QUERY_MONGO_DB shold read the whole collection use .setBody(constant("")) or .setBody([your mongodb-query]) if you want to read specific things.

from("direct:mongoSelect")
.setBody(constant(""))
.to(QUERY_MONGO_DB)

Finally, just from completeness, you write that you get results from mongo-db if you use the HTTP endpoint for the second route. I guess that you called the second route with a GET request and therefore the message has an empty body. That means you got back the whole collection from mongo-db.

burki
  • 6,741
  • 1
  • 15
  • 31
  • @buki Yes, My requirement is, to store a file content in mongodb using first route, is working fine, second route I have to read data from mongodb, this is exactly where the problem is, I don't have to use HTTP. I tried your second approach `from("direct:mongoSelect") .setBody("") .to(QUERY_MONGO_DB)` but `.setBody("")` has a compile time exception saying `The method setBody(Expression) in the type ProcessorDefinition is not applicable for the arguments (String)`. – Shamim Ahmad Mar 28 '18 at 06:18
  • Sorry, try `.setBody(constant(""))` or .setBody(constant(null)). I don't know if empty string or null makes a difference for mongodb. I also updated my answer. – burki Mar 28 '18 at 06:27