0
votes

I am new to camel, so this may be a simple problem to solve.

I have a spring-boot application with camel components which interacts with GitLab API.

My problem is that I need to keep the endpoint URIs in camel routes encoded, for example:

 from("direct:start")
  .setHeader("PRIVATE-TOKEN",constant("myToken"))
 .to("https://gitlab.com/api/v4/projects/12345/repository/files/folder%2Ffile%2Eextension/raw?ref=master")

When the route starts, the message is sent to

"https://gitlab.com/api/v4/projects/12345/repository/files/folder/file.extension/raw?ref=master"

which returns 404, because the parameter file_path has to be encoded, as said in the GitLab doc (I've cheked with a GET from curl: with the first URI a json is returned, with the second 404).

I tried to pass the last part of the URI as HTTP_QUERY, but in this case there is the "?" between it and the URI and I get 404 again:

https://gitlab.com/api/v4/projects/12345/repository/files/?folder%2Ffile%2Eextension/raw?ref=master

I tried adding the URI with the headerHTTP_URI: this time the URI is reached correctly, but I get null body instead of the json answer.

Any idea to solve this issue?

1

1 Answers

3
votes

I see that you already tried using HTTP_URI header. How did you set it? Try this:

 from("direct:start")
     .setHeader("PRIVATE-TOKEN", constant("myToken"))
     .setHeader(Exchange.HTTP_URI, simple("https://gitlab.com/api/v4/projects/12345/repository/files/folder%2Ffile%2Eextension/raw?ref=master"))
     .to("http:dummy");

This way you set the URI during the route execution, not in endpoint definition. According to docs:

Exchange.HTTP_URI: URI to call. Will override existing URI set directly on the endpoint. This URI is the URI of the HTTP server to call. Its not the same as the Camel endpoint URI, where you can configure endpoint options such as security etc. This header does not support that, its only the URI of the HTTP server.

Don't forget the dependency:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-http</artifactId>
</dependency>

The test:

@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
    return new RouteBuilder() {

        @Override
        public void configure() throws Exception {
            from("direct:start")
                .setHeader("PRIVATE-TOKEN", constant("myToken"))
                .setHeader(Exchange.HTTP_URI, simple("http://0.0.0.0:8080?param=folder%2Ffile%2Eextension/raw&ref=master"))
                .to("http:dummy");

            from("jetty:http://0.0.0.0:8080?matchOnUriPrefix=true")
                .setBody(constant("{ key: value }"))
                .setHeader(Exchange.CONTENT_TYPE, constant(MediaType.APPLICATION_JSON_VALUE))
                .to("mock:result");
        }
    };
}

@Test
public void test() throws InterruptedException {
    getMockEndpoint("mock:result").expectedHeaderReceived(Exchange.HTTP_QUERY, "param=folder%2Ffile%2Eextension/raw&ref=master");

    final Exchange response = template.send("direct:start", new Processor() {
        public void process(Exchange exchange) throws Exception {
            // nothing
        }
    });

    assertThat(response, notNullValue());
    assertThat(response.getIn().getHeader(Exchange.HTTP_URI).toString(), containsString("folder%2Ffile%2"));
    assertThat(response.getOut().getBody(String.class), containsString("{ key: value }"));


    assertMockEndpointsSatisfied();
}

I tried adding the URI with the headerHTTP_URI: this time the URI is reached correctly, but I get null body instead of the json answer.

Keep in mind that the response should be stored at the OUT body:

Camel will store the HTTP response from the external server on the OUT body. All headers from the IN message will be copied to the OUT message, so headers are preserved during routing. Additionally Camel will add the HTTP response headers as well to the OUT message headers.