001    package org.apache.geronimo;
002    
003    import java.io.IOException;
004    import java.net.URL;
005    import java.util.Date;
006    import java.util.Random;
007    import java.util.concurrent.ExecutorService;
008    import java.util.concurrent.Executors;
009    
010    import javax.servlet.ServletException;
011    import javax.servlet.http.HttpServlet;
012    import javax.servlet.http.HttpServletRequest;
013    
014    import org.apache.ahc.AsyncHttpClient;
015    import org.apache.ahc.codec.HttpRequestMessage;
016    import org.apache.catalina.CometEvent;
017    import org.apache.catalina.CometProcessor;
018    
019    /**
020     * Servlet implementation class for Servlet: AsyncServlet
021     * 
022     * @web.servlet name="AsyncServlet" display-name="AsyncServlet"
023     * 
024     * @web.servlet-mapping url-pattern="/async"
025     * 
026     */
027    public class AsyncServlet extends HttpServlet implements CometProcessor {
028            @Override
029            public void destroy() {
030                    // TODO Auto-generated method stub
031                    super.destroy();
032                    ahc.destroyAll();
033            }
034    
035            static final long serialVersionUID = 1L;
036    
037            private String remoteUrl;
038            private static AsyncHttpClient ahc;
039    
040            public void init() throws ServletException {
041                    remoteUrl = getServletConfig().getInitParameter("remoteUrl");
042    
043                    ExecutorService threadPool = Executors.newFixedThreadPool(8);
044        ahc = new AsyncHttpClient(threadPool);
045            }
046    
047            /**
048             * Process the given Comet event.
049             * 
050             * @param event
051             *            The Comet event that will be processed
052             * @throws IOException
053             * @throws ServletException
054             */
055            public void event(CometEvent event) throws IOException, ServletException {
056                    HttpServletRequest request = event.getHttpServletRequest();
057    
058                    String cometId = request.getSession(true).getId();
059                    System.out.println("");
060                    System.out.println("Session id: " + cometId + " "
061                                    + event.getEventType().toString());
062    
063                    if (event.getEventType() == CometEvent.EventType.BEGIN) {
064                            event.getHttpServletRequest().setAttribute(
065                                            "org.apache.tomcat.comet.timeout", new Integer(100 * 1000));
066                            event.setTimeout(100 * 1000);
067    
068                            if (request.getParameter("remoteUrl") != null) {
069                                    remoteUrl = request.getParameter("remoteUrl");        
070                            }
071    
072                            String remoteUri = request.getParameter("remoteUri");
073                            if (remoteUri == null) {
074                                    remoteUri = "/remoteApp/page";
075                            }
076                            
077                            URL url_connect = new URL(remoteUrl + remoteUri);                       
078                            Callback callback = new Callback(event.getHttpServletResponse(), cometId);
079                            //Callback callback = new Callback(event, cometId);
080                            HttpRequestMessage msgRequest = new HttpRequestMessage(url_connect, callback);
081    
082                            // If the file being served has other URIs in it, like say images,
083                            // subsequent calls are made to the remote app to retrieve those.
084                            // We don't want to set new delay times and status codes then.
085                            if (remoteUri.endsWith("page")) {
086                                    Integer[] params = generateRandomParams();
087                                    msgRequest.setParameter("sessionId", cometId);
088                                    msgRequest.setParameter("delay", params[0].toString());
089                                    msgRequest.setParameter("code", params[1].toString());
090                                    msgRequest.setTimeOut(1500);
091    
092                                    System.out.println("sessionId:" + cometId + "; delay:"
093                                                    + params[0] + "; code:" + params[1]);
094                            }
095          else {
096                                    System.out.println("msg request is " + msgRequest.getPath());
097                            }
098    
099                            msgRequest.setRequestMethod(HttpRequestMessage.REQUEST_GET);                    
100                            
101                            try {
102                                    callback.setTime(new Date().getTime());
103                                    ahc.sendRequest(msgRequest);
104                            } catch (Exception e) {
105                                    // TODO Auto-generated catch block
106                                    e.printStackTrace();
107                            }
108                    }
109        else if (event.getEventType() == CometEvent.EventType.ERROR) {
110                            event.close();
111                    }
112        else if (event.getEventType() == CometEvent.EventType.END) {
113                            event.close();
114                    }
115            }
116    
117            /**
118             * @return
119             */
120            protected Integer[] generateRandomParams() {
121                    Integer[] params = new Integer[2];
122                    final int[] codes = new int[] { 200, 302, 403, 404, 500 };
123    
124                    Random generator = new Random();
125    
126                    // generate a random delay between 10ms and 250 ms
127                    int delay = generator.nextInt(2000) + 10;
128                    params[0] = new Integer(delay);
129    
130                    // generate randomly one of http status codes.
131                    int index = generator.nextInt(codes.length);
132                    params[1] = new Integer(codes[index]);
133    
134                    return params;
135            }
136    
137    }