0

I see Apache Camel has a polling consumer (http://camel.apache.org/polling-consumer.html) and I was wondering if there is any way to use this from Akka to poll a HTTP REST API?

Other similar questions, Consumer Poll Rate with Akka, SQS, and Camel and Akka for REST polling seem to implement the polling logic themselves, I would prefer to just use what camel provides if possible.

Community
  • 1
  • 1
prio
  • 25
  • 3

1 Answers1

2

You have two options (the example codes are in Java):

1) Use the "timer" (or quartz for more advanced purposes) Camel components. Then you need a very simple Timer Actor which is calling in every period a new HTTProducer Actor:

    public class TimerConsumer extends UntypedConsumerActor{

    //Generates an event every 60 seconds:
    @Override
    public String getEndpointUri() {
        return "timer://foo?fixedRate=true&period=15000";
    }

    @Override
    public void onReceive(Object m) throws Exception {
        if (m instanceof CamelMessage){
            System.out.println("New Event (every 15sec)");
            Akka.system().actorOf(Props.create(HTTProducer.class)).tell("http://google.com", getSelf());
        }
    }
}

2) Use an Akka Scheduler

//Somewhere in the beginning of your application (Global.java for Play Framework 2)
ActorRef httpActor = Akka.system().actorOf(Props.create(HTTProducer.class));
//A message every 15s to the httpActor
Akka.system().scheduler().schedule(Duration.Zero(),
Duration.create(15, TimeUnit.SECONDS), httpActor, "http://google.com",
Akka.system().dispatcher(), null);

And the common HTTProducer Actor used for both options 1) and 2) is as follows (simplified for testing purposes):

public class HTTProducer extends UntypedProducerActor {

    @Override
    public String getEndpointUri() {
        return "http://empty.com";
    }

    @Override
    public Object onTransformOutgoingMessage(Object m) {
        if (m instanceof String){
            Map<String,Object> headers=new HashMap<>();
            headers.put(Exchange.HTTP_URI, (String)m);
            headers.put(Exchange.HTTP_METHOD, "GET");
            return super.onTransformOutgoingMessage(new CamelMessage(null,headers));
        }
        return super.onTransformOutgoingMessage(m);
    }

    @Override
    public void onRouteResponse(Object m) {
        if (m instanceof CamelMessage){
            CamelMessage message=(CamelMessage) m;
            System.out.println("Response: " + message.getBodyAs(String.class, getCamelContext()));
            System.out.println("Code: " + message.headers().get(Exchange.HTTP_RESPONSE_CODE).get());
        }
    }

So I recommend the second approach, since you just need to create an Actor and an Scheduler

Didac Montero
  • 2,046
  • 19
  • 27