KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mq > il > http > HTTPClientILService


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.mq.il.http;
23
24 import java.lang.reflect.Method JavaDoc;
25 import java.net.URL JavaDoc;
26 import java.util.Properties JavaDoc;
27
28 import org.jboss.logging.Logger;
29 import org.jboss.mq.Connection;
30 import org.jboss.mq.il.ClientIL;
31 import org.jboss.mq.il.ClientILService;
32
33 /**
34  * The HTTP/S implementation of the ClientILService object. One of these
35  * exists for each Connection object. Normally, this would be where you
36  * would boot up a client-side listener for the server to invoke. However
37  * in this case, we poll the server instead. In short, the ClientIL that we
38  * provide, once serialized and shipped to the server, simply places requests
39  * the server makes to it in a server-side storage mechanism. Then, when we
40  * send an HTTP request to the server, the servlet looks for queued requests
41  * waiting for us, batches them up and returns them in the response. Since
42  * we place ALL requests delivered to ANY instance of the ClientIL in a
43  * central storage queue, we have to have a way to get only the requests placed
44  * in storage by OUR ClientIL. Originally, I attempted to use the ConnectionId
45  * for this purpose, but it proooved to be less than ideal due to the fact that
46  * it created many cases where requests were being fielded to an instance of a
47  * ClientIL which was sent over the wire prior to the server returning our
48  * ConnectionId. This resulted in lost requests. Furthermore, since this had
49  * no control over exactly when the ConnectionId was set, we were forced to
50  * loop until it was not null. The current implementation doesn�t' suffer from
51  * these issues, as we can take full control over the process of setting our
52  * identifier and therefore, set the identifier on our ClientIL at creation time.
53  *
54  * @author Nathan Phelps (nathan@jboss.org)
55  * @version $Revision: 37459 $
56  * @created January 15, 2003
57  */

58 public class HTTPClientILService implements Runnable JavaDoc, ClientILService
59 {
60     
61     private static Logger log = Logger.getLogger(HTTPClientILService.class);
62     
63     private HTTPClientIL clientIL;
64     private Connection connection;
65     private URL JavaDoc url = null;
66     private long timeout = 60000;
67     private long restInterval = 0;
68     private Thread JavaDoc worker;
69     private String JavaDoc clientILIdentifier;
70     
71     private static int threadNumber= 0;
72     
73     public HTTPClientILService()
74     {
75         if (log.isTraceEnabled())
76         {
77             log.trace("created");
78         }
79     }
80     
81     public ClientIL getClientIL() throws Exception JavaDoc
82     {
83         if (log.isTraceEnabled())
84         {
85             log.trace("getClientIL()");
86         }
87         return this.clientIL;
88     }
89     
90     public void init(Connection connection, Properties JavaDoc props) throws Exception JavaDoc
91     {
92         if (log.isTraceEnabled())
93         {
94             log.trace("init(Connection " + connection.toString() + ", Properties " + props.toString() + ")");
95         }
96         this.connection = connection;
97         this.url = HTTPClient.resolveServerUrl(props.getProperty(HTTPServerILFactory.SERVER_URL_KEY));
98         this.clientILIdentifier = this.getClientILIdentifier(this.url);
99         this.clientIL = new HTTPClientIL(this.clientILIdentifier);
100         try
101         {
102             if (System.getProperties().containsKey(HTTPServerILFactory.TIMEOUT_KEY))
103             {
104                 this.timeout = Long.valueOf(System.getProperty(HTTPServerILFactory.TIMEOUT_KEY)).longValue();
105             }
106             else
107             {
108                 this.timeout = Long.valueOf(props.getProperty(HTTPServerILFactory.TIMEOUT_KEY)).longValue();
109             }
110             if (System.getProperties().containsKey(HTTPServerILFactory.REST_INTERVAL_KEY))
111             {
112                 this.restInterval = Long.valueOf(System.getProperty(HTTPServerILFactory.REST_INTERVAL_KEY)).longValue();
113             }
114             else
115             {
116                 this.restInterval = Long.valueOf(props.getProperty(HTTPServerILFactory.REST_INTERVAL_KEY)).longValue();
117             }
118         }
119         catch (Exception JavaDoc exception)
120         {} // we'll just use the default value
121
}
122     
123     public void start() throws Exception JavaDoc
124     {
125         if (log.isTraceEnabled())
126         {
127             log.trace("start()");
128         }
129         clientIL.stopped = false;
130         worker = new Thread JavaDoc(Connection.getThreadGroup(), this, "HTTPClientILService-" + threadNumber++);
131         worker.setDaemon(true);
132         worker.start();
133     }
134     
135     public void stop() throws Exception JavaDoc
136     {
137         if (log.isTraceEnabled())
138         {
139             log.trace("stop()");
140         }
141         clientIL.stopped = true;
142     }
143     
144     public void run()
145     {
146         if (log.isTraceEnabled())
147         {
148             log.trace("run()");
149         }
150         HTTPILRequest request = new HTTPILRequest();
151         request.setMethodName("clientListening");
152         while (clientIL.stopped == false)
153         {
154             try
155             {
156                 if (this.clientILIdentifier != null && clientIL.stopped == false)
157                 {
158                     request.setArguments(new Object JavaDoc[]
159                     {this.clientILIdentifier, new Long JavaDoc(this.timeout)}, new Class JavaDoc[]
160                     {String JavaDoc.class, Long JavaDoc.class});
161                     if (log.isDebugEnabled())
162                     {
163                         log.debug("Sending a request to '" + this.url.toString() + "' for ClientIL #" + this.clientILIdentifier + ".");
164                     }
165                     // The server responds with a HTTPILRequest object, not a HTTPILResponse object as you might expect.
166
// this is becuase the server is invoking the client.
167
HTTPILRequest[] response = (HTTPILRequest[])HTTPClient.post(this.url, request);
168                     if (response != null)
169                     {
170                         if (log.isDebugEnabled())
171                         {
172                             log.debug("Logging each response received in this batch for ClientIL #" + this.clientILIdentifier + ".");
173                         }
174                         for (int i = 0; i < response.length; i++)
175                         {
176                             if (log.isDebugEnabled())
177                             {
178                                 log.debug(response.toString());
179                             }
180                             Method JavaDoc method = this.connection.getClass().getMethod(response[i].getMethodName(), response[i].getArgumentTypes());
181                             method.invoke(this.connection, response[i].getArguments());
182                             if (log.isDebugEnabled())
183                             {
184                                 log.debug("Server invoked method '" + method.getName() + "' on ClientIL #" + this.clientILIdentifier + ".");
185                             }
186                         }
187                     }
188                     else
189                     {
190                         log.warn("The request posted to '" + this.url.toString() + "' on behalf of ClientIL #" + this.clientILIdentifier + " returned an unexpected response.");
191                     }
192                     
193                     try
194                     {
195                         if (log.isDebugEnabled())
196                         {
197                             log.debug("Resting " + String.valueOf(this.restInterval) + " milliseconds on ClientIL #" + this.clientILIdentifier + ".");
198                         }
199                         Thread.sleep(this.restInterval);
200                     }
201                     catch (InterruptedException JavaDoc exception)
202                     {} // We'll just skip the rest, and go ahead and issue another request immediatly.
203

204                 }
205                 else
206                 {
207                     log.warn("ClientIL Id is null, waiting 50 milliseconds to get one.");
208                     Thread.sleep(50);
209                 }
210             }
211             catch (Exception JavaDoc exception)
212             {
213                 if (log.isDebugEnabled())
214                 {
215                     log.debug("Exception of type '" + exception.getClass().getName() + "' occured when trying to receive request from server URL '" + this.url + ".'");
216                 }
217                 this.connection.asynchFailure(exception.getMessage(), exception);
218                 break;
219             }
220         }
221         if (this.clientIL.stopped)
222         {
223             if (log.isDebugEnabled())
224             {
225                 log.debug("Notifying the server that ClientIL #" + this.clientILIdentifier + " has stopped.");
226             }
227             try
228             {
229                 request.setMethodName("stopClientListening");
230                 request.setArguments(new Object JavaDoc[]
231                 {this.clientILIdentifier}, new Class JavaDoc[]
232                 {String JavaDoc.class});
233                 HTTPClient.post(this.url, request);
234             }
235             catch (Exception JavaDoc exception)
236             {
237                 if (log.isDebugEnabled())
238                 {
239                     log.debug("Attempt to notify the server that ClientIL #" + this.clientILIdentifier + " failed due to exception with description '" + exception.getMessage() + ".' This means that requests will stay in the storage queue even though the client has stopped.");
240                 }
241             }
242         }
243     }
244     
245     private String JavaDoc getClientILIdentifier(URL JavaDoc url) throws Exception JavaDoc
246     {
247         HTTPILRequest request = new HTTPILRequest();
248         request.setMethodName("getClientILIdentifer");
249         return (String JavaDoc)HTTPClient.post(url, request);
250     }
251 }
Popular Tags