Search code examples
apache-camelcamel-http

How to connect a Camel route to a REST Service to receive an event-stream


Within a Camel route I need to connect to a service with a HTTP GET request and leave the connection open to receive events. The Camel connection never receives events from the service.

I can use Postman to perform this operation successfully:successful Postman connection, so I know the service is running as expected.

My Camel Route calls the service endpoint as a GET with the same parameters used in Postman in the header of this call:

.setHeader(Exchange.HTTP_METHOD, constant(org.apache.camel.component.http.HttpMethods.GET))
.setHeader("Connection", simple("keep-alive"))
.setHeader("Accept", simple("text/event-stream"))
.setHeader("Accept-Encoding", simple("gzip, deflate, br"))
.setHeader("Postman-Token", simple("6ec7dfb3-6a4e-46ad-9f29-329a854f2649"))
.to("http://localhost:5000/events")

I know the service receives this call and creates event messages to send back, but they're never received by the Camel route. Also, a Postman connection that's made at the same time as the Camel connection does receive the event messages.

Q) What is the correct way to configure a Camel route to receive service events?


Solution

  • OkHttpClient can be used with a RealEventSource and a custom EventSourceListener to receive server side events.

    Steps:

    1. create a custom Listener class that extends EventSourceListener and has methods for handling events from the RealEventSource.
    • onEvent() processes the server-side-event data received from the Service
    • onOpen(), onClose(), onFailure() may also be useful
    1. create a Client class that instantiates your Listener
    • creates the OkHttpClient
    • creates the Request to send to the Service
    • creates a RealEventSource(Request, Listener)
    • calls realEventSource.connect(okHttpClient);
    1. create a AccessToken class for the values needed to access your Service
    2. in the camel Route class instantiate the Client
    • Client myClient = new Client();
    1. in Route.configure() call

      .process(new Processor() { public void process(Exchange exchange) throws Exception { myClient.Connect(); } })

    References: OkHttpClient realeventsource