All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.grizzly.http.embed.GrizzlyWebServer Maven / Gradle / Ivy

There is a newer version: 10.0-b28
Show newest version
/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the License).  You may not use this file except in
 * compliance with the License.
 *
 * You can obtain a copy of the license at
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL
 * Header Notice in each file and include the License file
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.
 * If applicable, add the following below the CDDL Header,
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
 */

package com.sun.grizzly.http.embed;

import com.sun.grizzly.arp.DefaultAsyncHandler;
import com.sun.grizzly.arp.AsyncFilter;
import com.sun.grizzly.arp.AsyncHandler;
import com.sun.grizzly.http.Management;
import com.sun.grizzly.http.SelectorThread;
import com.sun.grizzly.tcp.StaticResourcesAdapter;
import com.sun.grizzly.tcp.http11.GrizzlyAdapter;
import com.sun.grizzly.tcp.http11.GrizzlyAdapterChain;
import com.sun.grizzly.tcp.http11.GrizzlyRequest;
import com.sun.grizzly.tcp.http11.GrizzlyResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.ObjectInstance;
import javax.management.ObjectName;


/**
 * 

* This class creates a WebServer that listen for http request. By default, * creating an instance of this class can be used as it is to synchronously serve resources located * under {@link #webResourcesPath}. By default, the {@link StaticResourcesAdapter} is * used when there is no {@link GrizzlyAdapter} specified. The {@link StaticResourcesAdapter} * allow servicing of static resources like html files, images files, etc. * * The {@link GrizzlyAdapter} provides developpers with a simple and consistent mechanism for extending * the functionality of the Grizzly WebServer and for bridging existing * http based technology like JRuby-on-Rail, Servlet, Bayeux Protocol or any * http based protocol. *

You can extend the GrizzlyWebServer by adding one or serveral * {@link GrizzlyAdapter}. If more that one are used, the {@link GrizzlyAdapterChain} * will be used to invoke {@link GrizzlyAdapter}s one by one. As soon as one * {@link GrizzlyAdapter} can serve the request, the chain will be stopped and * the response will be sent back to the client. A {@link GrizzlyAdapter} gets invoked * as soon as the http request has been parsed and * decoded. The {@link GrizzlyAdapter#service(GrizzlyRequest,GrizzlyResponse} method is invoked with a * {@link GrizzlyRequest} and {@link GrizzlyResponse} that can be used to extend the * functionality of the Web Server. By default, all http requests are synchronously * executed. *

Asynchronous request processing is automatically enabled * as soon as one or several {@link AsyncFilter} are added, using the * {@link #addAsyncHandler} method. {@link AsyncFilter} can be used when * asynchronous operation are required, like suspending the current http request, * delaying the invokation of {@link GrizzlyAdapter} etc. The state of the * request processing can be managed using {@link AsyncExecutor}, like resuming * the process so {@link GrizzlyAdapter}s can be invoked. *

* The following picture describes how {@link AsyncFilter} and {@link GrizzlyAdapter} * are invoked. *


 * ----------------------------------------------------------------------------
 * - AsyncFilter.doFilter() ---> AsyncExecutor.execute()    -------|          -
 * -                                                               |          -
 * -                                                               |          -
 * -                                                               |          -
 * - AsyncFilter.doFilter() <-- GrizzlyAdapter2.service()   <------|          -
 * ----------------------------------------------------------------------------
 * 

* Here is some examples:


 * Synchronous Web Server servicing static resources
        GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
        try{
            ws.start();
        } catch (IOException ex){
            // Something when wrong.
        } 
 
 * Synchronous Web Server servicing customized resources
        GrizzlyWebServer ws = new GrizzlyWebServer("/var/www");
        try{
            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.
        } 
 * Synchronous Web Server servicing a Servlet
   
        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.
        } 
 * Synchronous Web Server servicing two Servlet
   
        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 sa = new ServletAdapter();
            sa.setRootFolder("/Path/To/Exploded/War2/File");
            sa.setServlet(new MySecondServlet());
            ws.addGrizzlyAdapter(sa);
  
            ws.start();
        } catch (IOException ex){
            // Something when wrong.
        } 
 * 
 * Asynchronous Web Server servicing customized resources
 * The example below delay the request processing for 10 seconds, without holding 
 * a thread.
 * 
        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.
        } 
 * Asynchronous Web Server servicing Servlet
 * The example below delay the request processing for 10 seconds, without holding 
 * a thread.
 * 
        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.
        }  
 * Asynchronous Web Server servicing Servlet and supporting the Bayeux Protocol

        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.setServlet(new MyServlet());
            ws.addGrizzlyAdapter(sa);
 
            ws.start();
        } catch (IOException ex){
            // Something when wrong.
        } 
 * Synchronous Web Server servicing static resources eand exposed using JMX Mbeans

        GrizzlyWebServer ws = new GrizzlyWebServer(path);    
        ws.enableJMX(new Management() {

            public void registerComponent(Object bean, ObjectName oname, String type) 
                    throws Exception{
                Registry.getRegistry().registerComponent(bean,oname,type);
            }

            public void unregisterComponent(ObjectName oname) throws Exception{
                Registry.getRegistry().
                        unregisterComponent(oname);
            }  
        });
        ws.start();
    }
}
 * 

* @author Jeanfrancois Arcand */ public class GrizzlyWebServer { // The port private int defaultPort = 8080; // The underlying {@link SelectorThread} private SelectorThread st; // SelectorThread mBean private ObjectInstance stMBean; // The underlying {@link GrizzlyAdapterChain} private GrizzlyAdapterChain adapterChains = new GrizzlyAdapterChain(); // List of {@link GrizzlyAdapter} private ArrayList adapters = new ArrayList(); // Are we started? private boolean isStarted = false; // List of {@link AsyncFilter} private ArrayList asyncFilters = new ArrayList(); // The path to static resource. private String webResourcesPath = "."; // The mBean default object name. private String mBeanName = "com.sun.grizzly:type=GrizzlyWebServer,name=GrizzlyHttpEngine-" + defaultPort; // The {@link Statistis} instance associated with this instance. private Statistics statistics; /** * Create a default GrizzlyWebServer */ public GrizzlyWebServer(){ createSelectorThread(defaultPort,5); } /** * Create a WebServer that listen on port * @param port The port opened */ public GrizzlyWebServer(int port){ createSelectorThread(port,5); } /** * Create a WebServer which server files from {@link #webResourcesPath} * @param webResourcesPath the path to the web resource (ex: /var/www) */ public GrizzlyWebServer(String webResourcesPath){ createSelectorThread(defaultPort, 5); this.webResourcesPath = webResourcesPath; } /** * Create a WebServer that listen on port * @param port The port opened */ public GrizzlyWebServer(int port, int maxThreads){ createSelectorThread(port, maxThreads); } /** * Create a WebServer that listen on port * @param port The port opened * @param webResourcesPath the path to the web resource (ex: /var/www) */ public GrizzlyWebServer(int port, String webResourcesPath){ createSelectorThread(port, 5); this.webResourcesPath = webResourcesPath; } /** * Create a WebServer that listen on port * @param port The port opened * @param maxThreads The maximum number of Thread created * @param webResourcesPath the path to the web resource (ex: /var/www) */ public GrizzlyWebServer(int port, int maxThreads, String webResourcesPath){ createSelectorThread(port, maxThreads); this.webResourcesPath = webResourcesPath; } /** * Create an underlying {@link SelectorThread} * @param port The port to listen to. * @param maxThreads the maximum number of Threads created. */ private void createSelectorThread(int port, int maxThreads){ st = new SelectorThread(); st.setPort(port); st.setMaxThreads(maxThreads); } /** * Return the underlying {@link SelectorThread}. Only advanced users * should manipulate that class. * @return {@link SelectorThread} */ public SelectorThread getSelectorThread(){ return st; } /** * Add an {@link AsyncFilter}. Adding {@link AsyncFilter} automatically * enable Grizzly Asynchronous Request Processing mode. {@link AsyncFilter}s * are always invoked before {@link GrizzlyAdapter} * * @param asyncFilter An {@link AsyncFilter} */ public void addAsyncFilter(AsyncFilter asyncFilter){ asyncFilters.add(asyncFilter); } /** * Add a {@link GrizzlyAdapter}. {@link GrizzlyAdapter} will be invoked by * Grizzly in the order they are added, e.g the first added is always the * first invoked. {@link GrizzlyAdapter}s * are always invoked after {@link AsyncFilter} * @param grizzlyAdapter a {@link GrizzlyAdapter} */ public void addGrizzlyAdapter(GrizzlyAdapter grizzlyAdapter){ adapters.add(grizzlyAdapter); } /** * Start the GrizzlyWebServer and start listening for http requests. Calling * this method several time has no effect once GrizzlyWebServer has been started. * @throws java.io.IOException */ public void start() throws IOException{ if (isStarted) return; isStarted = true; // Use the default if (adapters.size() == 0){ st.setAdapter(new StaticResourcesAdapter(webResourcesPath)); } if (adapters.size() == 1){ st.setAdapter(adapters.get(0)); } else { for (GrizzlyAdapter adapter: adapters){ adapterChains.addGrizzlyAdapter(adapter); } st.setAdapter(adapterChains); adapterChains.setHandleStaticResources(true); adapterChains.setRootFolder(webResourcesPath); } if (asyncFilters.size() > 0){ st.setEnableAsyncExecution(true); AsyncHandler asyncHandler = new DefaultAsyncHandler(); for (AsyncFilter asyncFilter: asyncFilters){ asyncHandler.addAsyncFilter(asyncFilter); } st.setAsyncHandler(asyncHandler); } try { st.listen(); } catch (InstantiationException ex) { throw new IOException(ex.getMessage()); } } /** * Enable JMX Management by configuring the {@link Management} * @param Management An instance of the {@link Management} interface */ public void enableJMX(Management jmxManagement){ if (jmxManagement == null) return; st.setManagement(jmxManagement); try { ObjectName sname = new ObjectName(mBeanName); jmxManagement.registerComponent(st, sname, null); } catch (Exception ex) { SelectorThread.logger().log(Level.SEVERE, "Enabling JMX failed", ex); } } /** * Return a {@link Statistics} instance that can be used to gather * statistics. By default, the {@link Statistics} object is not * gathering statistics. Invoking {@link Statistics#startGatheringStatistics} * will do it. */ public Statistics getStatistics(){ if (statistics == null){ statistics = new Statistics(st); } return statistics; } /** * Stop the GrizzlyWebServer. */ public void stop(){ if (!isStarted) return; isStarted = false; st.stopEndpoint(); } /** * Return an already configured {@link GrizzlyWebServer} that can serves * static resources. * @param path the directory to serve static resource from. * @return a ready to use {@link GrizzlyWebServer} that listen on port 8080 */ public final static GrizzlyWebServer newConfiguredInstance(String path){ GrizzlyWebServer ws = new GrizzlyWebServer(8080); ws.addGrizzlyAdapter(new GrizzlyAdapter(path){ { setHandleStaticResources(true); } @Override public void service(GrizzlyRequest request, GrizzlyResponse response) { try { response.setStatus(404); response.flushBuffer(); } catch (IOException ex) { Logger.getLogger(GrizzlyWebServer.class.getName()).log( Level.SEVERE, null, ex); } } }); return ws; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy