Saita
Saita

Reputation: 1044

Apache Camel - from jms to http

I have a spring-boot project using Apache Camel. I want to read a message from an activemq queue containing a file and send it to a web server.

I am trying to find the proper way to do this.

I believe I can make something like:

from("activemq:queue").bean(MyBean.class, "process")

And manually build a http request but I can't help thinking there is probably a better way to do it. Like:

from("activemq:queue").bean(MyBean.class, "process")
  .setHeader(Exchange.HTTP_METHOD,constant("POST"))
  .to("http://localhost:8080/test");

But I don't know how to manipulate the "exchange" to have a valid http Message.

MyBean receives an Exchange object containing a JmsMessage. I see that there is also a HTTPMessage but I don't think I should build that manually. (It requires HTTPRequest and Response objects I am not sure how to get.)

Can someone shed some light on this problem?

Update I am going for the bean solution.

from("activemq:queue").bean(MyBean.class, "sendMultipart");


public void sendMultipart(Exchange exchange) {
    ByteArrayInputStream in = new ByteArrayInputStream((byte[]) exchange.getIn().getBody());
    InputStreamBody contentBody = new InputStreamBody(in, ContentType.create("application/octet-stream"), "filename");
    HttpEntity entity = MultipartEntityBuilder
            .create()
            .addPart("file", contentBody)
            .build();
    HttpPost httpPost = new HttpPost("http://localhost:8080/upload/");
    httpPost.setEntity(entity);
    CloseableHttpClient httpClient = HttpClients.createDefault();
    try {
        CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
        System.out.println(httpResponse);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Upvotes: 1

Views: 1227

Answers (1)

raphaëλ
raphaëλ

Reputation: 6523

Updated post

I found this http://hilton.org.uk/blog/camel-multipart-form-data. It allows you to leverage the camel http component.

"jms:queue/SomeQ" ==> {
    process(toMultipart)
    setHeader(Exchange.CONTENT_TYPE, "multipart/form-data")
    process((e: Exchange) => e.getIn.setHeader(Exchange.HTTP_URI,"http://localhost:8111/foo"))
    to ("http:DUMMY")
}

def toMultipart(exchange: Exchange): Unit = {

  val data = exchange.in[java.io.File]

  val entity = MultipartEntityBuilder.create()
  entity.addBinaryBody("file", data)
  entity.addTextBody("name", "sample-data")

  // Set multipart entity as the outgoing message’s body…
  exchange.in = entity.build
}

Side note: this would really be a nice use-case to try-out reactive streams.

Original post

I am still having some problems understanding your actual problem. Perhaps some code might help:

I am now assuming you are receiving bytes in some character encoding and want to sent it onward to a dynamically established http-endpoint.

Is the following something you are looking for (code is in camel's scala-dsl)

"jms:queue/SomeQ" ==> {
    convertBodyTo(classOf[String],"UTF-32" )
    process((e: Exchange) => e.in = e.in[String].toUpperCase + "!")
    process((e: Exchange) => e.getIn.setHeader(Exchange.HTTP_URI,"http://localhost:8111/foo"))
    to ("http:DUMMY")
}

It will be send as an HTTP POST as the body is not null.

I receive it all well on another endpoint i created to ensure the code above is correct:

"jetty:http://localhost:8111/foo" ==> {
  log("received on http 8111 endpoint ${body}")
 }

Upvotes: 1

Related Questions