Implementing an Event for a Provider

Procedure

  1. Write an event class that extends the AbstractExpressoEvent class.
  2. Define an event data class whose object represents and returns event data generated by the event back to the Expresso server.
  3. Override the subscribeToEvent() and unSubscribeFromEvent() to handle subscriptions for the event. The subscribeToEvent() method is called with a providerWebhookUrl parameter which is generated specific to every event by the provider server. This URI listens to a POST call from external services and subsequently routes it to the event through the onExternalEvent() method.
  4. If the provider requires communication with external services, handle it in the overridden onExternalEvent() method.
  5. Notify the subscriber using the notifySubscriber() method either in the onExternalEvent() method itself, or elsewhere as per specific provider requirement.

Writing a Class that Extends the AbstractExpressoEvent Class

This sample illustrates the methods that the extending class must implement. Here, TimerEvent.java extends the AbstractExpressoEvent class.
public class TimerEvent extends AbstractExpressoEvent 
{

// provider specific fields

	private boolean isRunning = false;
	private Timer timer;

/ EventData class: Every event needs to publish data back to the Expresso 
//server. On specific intervals, the timer event will notify the Expresso
//along with an event data object of type TimerEventData. This event data 
//class is event specific. This class is set while creating an object in 
//the provider class. pojoProvider internally converts the data to JSON 
//format as required by Expresso while publish events using an object of 
//the event data class.

public static class TimerEventData {

		private String message;

		public void setMessage(String message) {
			this.message = message;
		}

		public String getMessage() {
			return message;
		}

	}	

// subscribeToEvent is called by the pojoProvider on two occasions. When the 
//first subscription to an event is received, and if pojoProvider is 
//restarted and existing subscriptions from Expresso were present on it. The 
//pojoProvider sends a providerWebhookUrl to the provider. This is meant to 
//be used by the provider if it listens to another service. For timer, it 
//isn’t required, but it is used in the TwilioProvider as the url to listen 
//for messages coming from Twilio. 
//For example: http://(somehost).com:80/events/Twilio/SMSReceived. Such url 
//is then registered with Twilio for listening to webhook callbacks from 
//Twilio. For timer, the events are generated locally and thus the 
//providerWebhookUrl isn’t required. On receving a call, this method should 
//implement logic to initiate the publishing of events. Here, the 
//timer.start() call does the same.

@Override
public boolean subscribeToEvent(URI providerWebhookUrl) 
{
	timer = new Timer();
	isRunning = true;
	timer.start();
	return true;
}
	
//Once the subscription is received, in case the provider depends on external 
//service to notify it with data, the onExternalEvent method is called along 
//with the request object and a response object. The provider should extract 
//data from the request object and set the response object according to what 
//the external service desires. Please refer to the TwilioReceiveSMS class 
//in the samples to see this usage. For timer, as no external service is 
//communicating with it, This method is left blank. On receiving of external 
//event, or on fulfilment of the providers own conditions, the provider has 
//to call the notifySubscriber() method passing the event data object 
//to it. In this case, we are doing so after regular intervals using the 
//Timer class.

@Override
public void onExternalEvent(HttpServletRequest request,HttpServletResponse response) 
{
		// TODO Auto-generated method stub
}

class Timer extends Thread {

		private int interval;
		private final TimerEventData eventData;

Timer() 
{
/** Use data from properties file to decide time interval between
  * events and the message to send in event data. Default is interval
  * is 30000 ms and default message is "Hello Expresso"
*/
	intrvl = TimerProvider.timerData.get(TIMER_INTERVAL);
	if (intrvl == null)
	   	intrvl = "30000";
	interval = Integer.parseInt(intrvl);
	msg = TimerProvider.timerData.get(TIMER_MESSAGE);
	if (msg == null)
		   msg = "Hello Expresso";
	/*
	 * Create object of class that represents the event data.
	*/
	eventData = new TimerEventData();
	eventData.setMessage(msg);

}

		@Override
		public void run() {
			while (isRunning) {
				try {
					Thread.sleep(interval);
					/*
					 * Notify subscriber
					 */
					notifySubscriber(eventData);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} // loop ends
		} // run() ends
	} // class Timer ends
	
//unSubscribeFromEvent is called when the last subscriber unsubscribes from 
//the event. In this method the provider is supposed to handle logic to 
//stop sending events. In the TimerProvider we set the flag to false.

@Override
public boolean unSubscribeFromEvent() 
{
	isRunning = false;
	return true;
}

	
}