Home > Uncategorized > Extending the Grizzly HTTP Runtime

Extending the Grizzly HTTP Runtime

Project Grizzly provides developers with a simple and consistent mechanism for extending the functionality of the Grizzly HTTP Runtime and for bridging existing HTTP based technologies like JRuby-on-Rail, Grail, Servlet, the Bayeux Protocol or any http based protocol.

IMG_0320.JPG

There is three important classes to know when you want to extend (and embed):

  • GrizzlyAdapter: The GrizzlyAdapter is the main extensible point when you want to write an http based extension. This class is invoked by the Grizzly Http Runtime as soon as the http request has been parsed. It’s main method is defined as service(GrizzlyRequest req, GrizzlyResponse res). You can get all the http information from the GrizzlyRequest and write the response using the GrizzlyResponse. Grizzly ships with several implementation of the GrizzlyAdapter: ServletAdapter, CometdAdapter, StaticResourceAdapter, etc. You can look at the details by browsing the code from here
  • AsyncFilter: AsyncFilter are helpful when you want to write an asynchronous request processing based web server. AsyncFilter allows you to suspend the processing of an http request, and resume it once you are ready. When suspending the request execution, an AsyncFilter doesn’t block on a Thread so you don’t waste a Thread until the execution is resumed. AsyncFilter always execute before any GrizzlyAdapter
  • GrizzlyWebServer: The main entry point. You always first create an instance of the GrizzlyWebServer, and then add GrizzlyAdapter(s) and AsyncFilter(s).

Sound complicated? Not at all! Let’s describe some really simple examples.

First, let’s create a WebServer that serve static resources:

        GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
        try{
            ws.start();
        } catch (IOException ex){
            // Something when wrong.
        }

Now let’s write a very simple GrizzlyAdapter that return an html page when a static resource is not found.

        GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
        try{
            ws.addGrizzlyAdapter(new GrizzlyAdapter(){  
                
                public void service(GrizzlyRequest request, GrizzlyResponse response){
                    try {
                        response.getWriter().println("Grizzly is soo cool..but you request cannot be found!");
                    } catch (IOException ex) {                        
                    }
                }
            });
            ws.start();
        } catch (IOException ex){
            // Something when wrong.
        }

Now let’s add Servlet support to our WebServer (note that the Grizzly’s Servlet support is limited in term of functionalities..no deployment support, all done programatically)

   
        GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
        try{
            ServletAdapter sa = new ServletAdapter();
            sa.setRootFolder("/Path/To/Exploded/War/File");
            sa.setServlet(new MyServlet());
            ws.addGrizzlyAdapter(sa);
            ws.start();
        } catch (IOException ex){
            // Something when wrong.
        } 

Well, why not adding two Servlet support

        GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
        try{
            ServletAdapter sa = new ServletAdapter();
            sa.setRootFolder("/Path/To/Exploded/War/File");
            sa.setServlet(new MyServlet());
            ws.addGrizzlyAdapter(sa);
  
            ServletAdapter sa2 = new ServletAdapter();
            sa2.setRootFolder("/Path/To/Exploded/War2/File");
            sa2.setServlet(new MySecondServlet());
            ws.addGrizzlyAdapter(sa2);
  
            ws.start();
        } catch (IOException ex){
            // Something when wrong.
        }

Easy, it is (to speak like Yoda). Now let’s go back to basic, which is to serve static resources. Let’s assume we want to delay the request processing when we are under load, using an AsyncFilter. Let’s assume for now that all requests will be suspended 10 seconds before they get executed by the GrizzlyAdapter.

        GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
        try{
            ws.addAsyncFilter(new AsyncFilter() {
                private final ScheduledThreadPoolExecutor scheduler = 
                        new ScheduledThreadPoolExecutor(1);
                public boolean doFilter(final AsyncExecutor asyncExecutor) {
                    //Throttle the request
                    scheduler.schedule(new Callable() {
                        public Object call() throws Exception {
                            asyncExecutor.execute();
                            asyncExecutor.postExecute();
                            return null;
                        }
                    }, 10, TimeUnit.SECONDS);
                    
                    // Call the next AsyncFilter
                    return true;
                }
            });
                                        
            ws.addGrizzlyAdapter(new GrizzlyAdapter(){                  
                public void service(GrizzlyRequest request, GrizzlyResponse response){
                    try {
                        response.getWriter().println("Grizzly is soon cool");
                    } catch (IOException ex) {                        
                    }
                }
            });
            ws.start();
        } catch (IOException ex){
            // Something when wrong.
        }

This is cool, is it? Now let’s add Servlet to the picture:

        GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
        try{
            ws.addAsyncFilter(new AsyncFilter() {
                private final ScheduledThreadPoolExecutor scheduler = 
                        new ScheduledThreadPoolExecutor(1);
                public boolean doFilter(final AsyncExecutor asyncExecutor) {
                    //Throttle the request
                    scheduler.schedule(new Callable() {
                        public Object call() throws Exception {
                            asyncExecutor.execute();
                            asyncExecutor.postExecute();
                            return null;
                        }
                    }, 10, TimeUnit.SECONDS);
                    
                    // Call the next AsyncFilter
                    return true;
                }
            });
  
            ServletAdapter sa = new ServletAdapter();
            sa.setRootFolder("/Path/To/Exploded/War/File");
            sa.setServlet(new MyServlet());
            ws.addGrizzlyAdapter(sa);
 
            ws.start();
        } catch (IOException ex){
            // Something when wrong.
        }

Miam Miam! OK now let do something really really complicated :-). Let’s add Comet into the picture. Naa not enough complicated. Let’s add the Bayeux Protocol (cometd) but also be able to serve static resources and Servlet.

        GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
        try{
            // Add Comet Support
            ws.addAsyncFilter(new CometAsyncFilter());
 
            //Add Bayeux support
            CometdAdapter cometdAdapter = new CometdAdapter();
            ws.addGrizzlyAdapter(cometdAdapter);
  
            ServletAdapter sa = new ServletAdapter();
            sa.setRootFolder("/Path/To/Exploded/War/File");
            sa.setContextPath("/servlets/");
            sa.setServlet(new MyServlet());
            ws.addGrizzlyAdapter(sa);
 
            ws.start();
        } catch (IOException ex){
            // Something when wrong.
        } 

Wow. With just a couple of line we were able to create a Web Server that supports the Bayeux Protocol, a single Servlet and static resources. Now you can do things much more complicated, like writing complex and powerful GrizzlyAdapter, and call it GlassFish v3 :-). v3 is a good example of how easy it is to build really powerful HTTP extension using the Grizzly extensible point like the GrizzlyAdapter.

Want to give it a try? Download the Grizzly HTTP extension, add it to your classpath, and look at the GrizzlyWebServer API. Now if you want to do things more complicated liked adding JMX support, monitoring, etc, then read that old blog serie and look at the now infamous SelectorThread documentation :-). If you have question, just stop by users@grizzly.dev.java.net…we have more and more peoples shaking the Grizzly those days!

_uacct = “UA-3111670-1″;
urchinTracker();

technorati:

About these ads
Categories: Uncategorized
  1. sam
    June 6, 2011 at 2:12 pm | #1

    This is great,But i was wondering whether it was possible to start the webserver on any other host other than 0.0.0.0?

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 50 other followers

%d bloggers like this: