View Javadoc

1   /***
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Exoffice Technologies.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Exoffice Technologies. Exolab is a registered
23   *    trademark of Exoffice Technologies.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   *
42   * Copyright 2001-2002 (C) Exoffice Technologies Inc. All Rights Reserved.
43   *
44   * $Id: HttpJmsClientServlet.java,v 1.7 2003/08/30 08:00:53 tanderson Exp $
45   *
46   * Date				Author  Changes
47   * Fri 21 Sep 2001	mourikis    Created
48   *
49   */
50  
51  package org.exolab.jms.client.http.servlet;
52  
53  import java.io.BufferedInputStream;
54  import java.io.BufferedOutputStream;
55  import java.io.IOException;
56  import java.io.ObjectInputStream;
57  import java.io.ObjectOutputStream;
58  import java.util.HashMap;
59  import java.util.Iterator;
60  import java.util.Vector;
61  
62  import javax.servlet.http.HttpServlet;
63  import javax.servlet.http.HttpServletRequest;
64  import javax.servlet.http.HttpServletResponse;
65  
66  import org.exolab.core.ipc.Client;
67  
68  
69  /***
70   * This servlet forwards messages from the OpenJMS server to clients
71   *
72   * @version     $Revision: 1.7 $ $Date: 2003/08/30 08:00:53 $
73   * @author      <a href="mailto:mourikis@intalio.com">Jim Mourikis</a>
74   * @author      <a href="mailto:tima@intalio.com">Tim Anderson</a>
75   */
76  public class HttpJmsClientServlet extends HttpServlet {
77  
78      /***
79       * The list of active client connections, keyed on host and port.
80       */
81      private HashMap _connections = new HashMap();
82  
83      /***
84       * The content type of the data.
85       */
86      private static final String CONTENT_TYPE = "text/html";
87  
88      /***
89       * Called by the servlet container to indicate to a servlet that the
90       * servlet is being placed into service.
91       */
92      public void init() {
93          log("OpenJMS client servlet ready");
94      }
95  
96      /***
97       * Handle HTTP POST requests
98       *
99       * @param request contains the request the client has made of the servlet
100      * @param response contains the response the servlet sends to the client
101      * @throws IOException if an I/O error is encountered
102      */
103     public void doPost(HttpServletRequest request,
104                        HttpServletResponse response) throws IOException {
105 
106         ObjectInputStream input = new ObjectInputStream(
107             new BufferedInputStream(request.getInputStream()));
108 
109         ObjectOutputStream output = new ObjectOutputStream(
110             new BufferedOutputStream(response.getOutputStream()));
111         response.setContentType(CONTENT_TYPE);
112 
113         String host = request.getHeader("jms-host");
114         int port = request.getIntHeader("jms-port");
115 
116         try {
117             Object object = input.readObject();
118             if (object instanceof Vector) {
119                 Vector message = (Vector) object;
120                 Client connection = getConnection(host, port);
121                 synchronized (connection) {
122                     connection.send(message);
123                     String type = request.getHeader("jms-response");
124                     if (type != null && type.equals("yes")) {
125                         message = (Vector) connection.receive();
126                         output.writeObject(message);
127                     }
128                 }
129 
130                 response.setStatus(HttpServletResponse.SC_OK);
131             } else if (object instanceof String &&
132                        "close".equals(object)) {
133                 removeConnection(host, port);                
134             } else {
135                 log("Received invalid request");
136                 response.setStatus(
137                     HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
138                 output.writeObject("Object is NULL, or UNEXPECTED type");
139             }
140         } catch (Exception exception) {
141             log("Failed to process request", exception);
142             removeConnection(host, port);
143             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
144             output.writeObject(exception.getMessage());
145         } finally {
146             output.flush();
147         }
148     }
149 
150     /***
151      * Clean up client connections
152      */
153     public synchronized void destroy() {
154         Iterator iterator = _connections.values().iterator();
155         while (iterator.hasNext()) {
156             Client client = (Client) iterator.next();
157             try {
158                 client.close();
159             } catch (IOException ignore) {
160             }
161         }
162     }
163 
164     /***
165      * Returns a cached TCP connection for the specified host name and
166      * port number, creating one if none exists.
167      *
168      * @param host the host name of the client
169      * @param port the TCP port number
170      * @throws IOException if a connection cannot be establised
171      */
172     private synchronized Client getConnection(String host, int port)
173         throws IOException {
174         String key = host + ":" + port;
175         Client client = (Client) _connections.get(key);
176 
177         if (client == null) {
178             try {
179                 client = new Client(host, port);
180             } catch (IOException exception) {
181                 throw new IOException("Failed to connect to host=" + host
182                                       + ", port=" + port + ": "
183                                       + exception.getMessage());
184             }
185             _connections.put(key, client);
186         }
187         return client;
188     }
189 
190     /***
191      * Remove a cached TCP connection.
192      *
193      * @param host the host name of the client
194      * @param port the TCP port number
195      */
196     private synchronized void removeConnection(String host, int port) {
197         String key = host + ":" + port;
198         Client client = (Client) _connections.remove(key);
199         if (client != null) {
200             try {
201                 client.close();
202             } catch (IOException ignore) {
203                 // may already be closed.
204             }
205         }
206     }
207 
208 } //-- HttpJmsClientServlet