Pushing realtime updates for your backend to ADF Faces

Imagine you have some services which frequently triggers your backend to process some data and you need to display these changes on the UI… The most reasonable pattern is using Comet!

ADF Faces has great and flexible support for Comet with its ADS facility. This post quickly describes you to push data from a backend to your client. In order to avoid writing and faking a “busy” backed, I use the twitter update stream – which actually provides data in REALTIME to your application.

The previous blog described the pattern how to connect to the Twitter streaming, by using Apache Wink (a REST client API).

Now within the “while loop” you need to notifiy ADS that a new tweet is waiting to be displayed by the client, like:

while(condition)
{
 // parse the input stream's JSON to nick, tweetMsg etc

 listener.onTweet(new TweetBean(nick, image, tweetMsg));
}

So from the “Twitter backend” you notify a listener that a new tweet arrived on the realtime twitter stream.

The easiest way to combine Twitter and ADS is by using the “Proxy approach”. Let your own ActiveCollectionModelDecorator class implement an interface such as “ITwitterUpdateListener”.  So, the above “listener” is actually this class. The code for the onTweet() finally creates and submits the ADS event(s):

public void onTweet(TweetBean tweet)
{
 // start the preparation for the ADS update
 atm.prepareDataChange();

 // create an ADS event.....
 // this class is not part of the API
 ActiveDataUpdateEvent event =
 ActiveDataEventUtil.buildActiveDataUpdateEvent(
// type of the event
 ActiveDataEntry.ChangeType.INSERT,
// the changeCount
 atm.getCurrentChangeCount(),
// rowKey
 new Object[] {tweets.indexOf(tweet)},
// insert at ...
 new Object[] {tweets.indexOf(tweet)-1},
// attribute/property names that change
 new String[] {"image", "nick", "message"},
// the payload for the above attributes
 new Object[] {
tweet.getImage(),
tweet.getNick(),
tweet.getMessage() }
 );

 // deliver the new Event object to the ADS framework
 atm.notifyDataChange(event);
}

Now you can use the <af:table> component to display the information of the tweets. In the example, we show the name and the picture of the poster and the
actual tweet message:

<af:table value="#{bean.activeCollectionModelDecoratorImpl}"
var="tweet" id="t1" ...>

 <af:column width="50" id="c2">

<af:outputText  escape="false"
value="#{tweet.image}" id="ot2"/>

</af:column>

<af:column headerText="USER" id="c1">
 <af:outputText value="#{tweet.nick}" id="ot1"/>
 </af:column>
 <af:column width="350" headerText="Message" id="c3">
 <af:outputText value="#{tweet.message}" id="ot3"/>
 </af:column>
</af:table>

Note: For the image we say escape:false as we stream HTML of the actual twitter location. Note that usually this can be dangerous on all outputText (cross site scripting),but here we want it, since it is a fast way to resolve the IMG…

ADF Faces and ADS is a powerful tool and you can observe twitter trends with out issues! However note that on observing twitter trends, you are kinda spammed by the backend… Therefore you need to think about the “load” of information that your user is potentially interested in..

Another interesting example on how to combine Twitter and “real time ADF Faces” is here. However the only thing there that is not really realtime is that the code polls twitter, which is fine since not all features are yet supported by the Twitter Streaming API!

Generally: This can not be used with Twitter only… You could also connect your 11g database nofifications to push data to the UI. Did that with Frank Nimphius for OpenWorld. (Not sure if his blog actually has the demo code).

Enjoy!

Twitter Streaming API and Apache Wink

During 2009 Twitter launched their Streaming API, which allows developers to get an (almost) real-time notification of tweets. The “filter.json” resource allows some filtering of the content. With CURL you could listen to the Twitter stream like:

curl http://stream.twitter.com/1/statuses/filter.json?track=myKeyWord -umyUserAccount:password

Note that the track parameter could be also send to the stream.twitter.com server (which is a Jetty-powered service) as a POST (-d option).

To have a bit more comfort, one wants to use a (Java) REST API. Apache Wink is pretty nice and listening to the stream is simple:

ClientConfig cc = new ClientConfig();

String logon = "myAccount:myPasswd";
String encodedLogon = new BASE64Encoder().encode(logon.getBytes());

RestClient client = new RestClient(cc);
Resource twitter = client.resource("http://stream.twitter.com/1/statuses/filter.json?track=Berlin");

twitter.header("Authorization", "Basic " + encodedLogon);
twitter.contentType(MediaType.APPLICATION_FORM_URLENCODED_TYPE);
twitter.accept(MediaType.APPLICATION_JSON_TYPE);

// do the HTTP GET
ClientResponse cr = twitter.get();

// we want the input stream
InputStream is =  cr.getEntity(InputStream.class);

try
{
BufferedReader r = new BufferedReader(new InputStreamReader( is, "UTF8"));
while(someCondition)
{
String rawJsonTweetData = r.readLine();
// parse the tweet and submit to your "system"
...

Once you submitted the HTTP_GET you need to transform the returned value to be InputStream. Now the stream is in your hand and you can parse the returned JSON value as you like. From there you can use the streamed data in your system.

I used the stream value to visualize the data with ADF Faces’ comet facility (aka ADS). I created a simple monitoring processor, which receives the tweets and submits them to the ADS subsystem. From there I “pushed” them to the browser, so my ADF Faces table got updated, with the latest tweets.

Note: “Following” a Twitter trend key-word can generate quite a huge amount of data, which could flood your UI (or other processing (sub)system)

There are some libraries available that give similar access to the streaming API. I found the TweetStream Ruby GEM pretty interesting, as you can run it as daemon.