Showing posts with label rss. Show all posts
Showing posts with label rss. Show all posts

Thursday, July 1, 2010

RSS, Lucene, and REST

Sorry for the horrible title. I struggled trying to come up with a worthy title, but after a few minutes I decided to not let perfection get in the way of good.

My team has recently worked on a new feature I am pretty excited about: adding support for RSS/Atom in our application. I know your thinking so what. It's not really the what I am excited about but the how. What I'm really excited about was how the story was defined and implemented.

Approach
We had the simple requirement from a newer customer to provide an RSS feed for newly created items. This actually wasn't the first time for this requirement. We prototyped a similar capability a long time ago using OpenESB and the RSS BC, but for multiple reasons it just didn't work out.

So our first decision had to answer: how we were going to implement it......again, but better. Before the sprint began, a few of us got together and hashed out a potential solution: how about we use the Search REST Service, which is backed by Lucene, to support Advanced searches and return RSS?

Why does this excite me so much? To understand that I need to explain our application at a high level. It's a completely javascript-based application using ExtJS (now sencha), backed by REST Services using Jersey. Consequently, we have a lot of REST Services. Right now those REST Services support returning XML or JSON using a custom Response Builder we have created internally.

I'm excited because this single user story could have a huge improvement on the entire system:

  1. If we modified the Search Service to return RSS, then all our REST Services could support RSS.
  2. The REST Service would now support Advanced searches. Previously, it only really supported basic keyword searches.
  3. Any search they perform could now be subscribe to via RSS.
Implementation
I'm not going to go into every detail on how it was done. I wasn't even actually the one who implemented it (see Matt White. He did a fantastic job.). We did have one major hurdle we had to overcome, and that was how to index items to enable advanced searches like Status=New.

Previously this wasn't possible given how we were indexing our items. We were basically indexing the item by building up a large String containing all the item information like the following:
import org.apache.lucene.document.Document
import org.apache.lucene.document.Field

def Document createDocument(item) {
    Document d = new Document()
    
    doc.add(new Field("content",
        getContent(item),
        Field.Store.NO,
        Field.Index.ANALYZED))
        
    return d
}

def String getContent(item) {
    def s = new StringBuilder()
    
    s.append(item.getTitle()).append(" ")
    s.append(item.getStatus()).append(" ")
    s.append(item.getPriority()).append(" ")
    s.append(item.getDescription()).append(" ")
    
    return s.toString()
}

The problem with this is performing a search for "New" would have returned any item with a status of New as well as any items that contained the word New. The solution was to just add another Field to the Document.
doc.add(new Field("Status",
    item.getStatus(),
    Field.Store.NO,
    Field.Index.NOT_ANALYZED));

Now the Search Service could support advanced searches like: Status:"New". You should put the value in quotes in case the value contains spaces (ie Status:"In Progress"). And since Lucene is so powerful, it also means the follow search would work: Status:"New" AND Priority:"High" AND "Hurricane". Now users have the freedom to subscribe to a near limitless amount of RSS feeds based on Advanced Searches.

Start to Finish
I think there were several reasons why this story was a success in my eyes. Most importantly where the two really smart co-workers who worked on it: Matt White and Chuck Hinson. All three of us knew of this user story ahead of time and we were able to discuss it technically days before backlog selection. This allowed us to brainstorm some ideas. Once we narrowed it down, we spent some more time separately looking into the code to find out the level of difficulty and if Advanced Searches like Status:New would be possible. Overall, together I'd say we spent 3-4 hours doing the preliminary work. Doing that preliminary work I think really enabled us to give a proper WAG for the story.

I really can't speak for how the development went (I was at Disney World for 10 days with the family), but I was really impressed with the tests Matt wrote. He wrote a number of unit tests making sure advanced searches worked and basic searches still worked. On top of that, he wrote an overall functional test using HttpBuilder executing the REST Service just as our javascript client would.

Finally, once the main work was finished, we uploaded a diff file to our internal instance of Review Board. From there I was able to perform a peer review where we found a minor bug in the changes.

Summary
I am sure it's not an original idea, but I thought it was a fun User Story that hopefully will provide a lot of value beyond what was originally estimated. Ideally, this might help others who are in similar situations.

Thursday, January 14, 2010

DZone Top Links Feed


I have a problem: The DZone Top Links section is great but doesn't support an RSS feed. It has feeds for just about everything else. This would be like digg or tweetmeme not having a feed for their most popular links. What makes it worse is I read a majority of their Top Links, but in order to do so I have to keep a tab open in firefox. Wouldn't it be great if I could just subscribe via Google Reader? And now thanks to Yahoo Pipes's screen scrapping capability you can.

Click this link to subscribe to the DZone Top Links Feed: http://pipes.yahoo.com/jlorenzen/dzonetoplinks.

This was accomplished by cloning my RssHuskerPedia pipe and changing a few things around. These pipes depend on the Fetch Page module which essentially lets you scrap the page allowing you to create a list. This feed doesn't contain all the metadeta that would normally come from an official DZone feed, but it supports the basics and prevents me from missing great articles that I would have normally missed.

Please vote this up on DZone to get the word out and hopefully DZone will create an official one. If it gets voted up enough and makes it to the Top Links section, hopefully you won't get stuck in an infinite loop.

Wednesday, October 15, 2008

Using Yahoo Pipes screen scraping to create an RSS Feed

The internet amazes me. Every time I use it, or write something for it, I continue to be blown away. Take for example, my favorite website for Husker information: http://www.huskerpedia.com (for those that don't know, what I mean by husker information is Nebraska Cornhusker Football. I was born in Nebraska so I naturally follow the cornhuskers.). Someone takes the time to consolidate all husker information and updates this site. It is the de facto standard for Husker news. Unfortunately, this site does not come with any type of notifications via an RSS feed.

Now this site does not necessarily amaze me, but rather how I can take a tool like Yahoo Pipes, scrape the latest news, and in a couple of hours subscribe to that feed in Google Reader. Not only that, but I cloned Paul Arterburn's Huskerpedia Pipe to get started and now everyone can take advantage of my new feed by either subscribing to it, making it better, or cloning it for their own use.

This would make the second time I have used Yahoo Pipes to accomplish something complex very easily. Several months ago, I created a pipe called the Gestalt Shared Feed, that combined all of my co-workers shared items from their Google Reader feed. This allowed us to read the best of the best among ourselves and has really helped our communication. I think we have about 10 people who share items and many more who subscribe to it.

Check out my RssHuskerPedia Pipe and view the source if you are curious. See below for the before and after.