KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > joram > client > jms > soap > SoapConnection


1 /*
2  * JORAM: Java(TM) Open Reliable Asynchronous Messaging
3  * Copyright (C) 2001 - 2006 ScalAgent Distributed Technologies
4  * Copyright (C) 1996 - 2000 Dyade
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA.
20  *
21  * Initial developer(s): Frederic Maistre (INRIA)
22  * Contributor(s): ScalAgent Distributed Technologies
23  */

24 package org.objectweb.joram.client.jms.soap;
25
26 import java.io.IOException JavaDoc;
27 import java.net.MalformedURLException JavaDoc;
28 import java.net.URL JavaDoc;
29 import java.util.Timer JavaDoc;
30 import java.util.Vector JavaDoc;
31 import java.util.Hashtable JavaDoc;
32 import java.lang.reflect.Method JavaDoc;
33
34 import javax.jms.IllegalStateException JavaDoc;
35 import javax.jms.JMSException JavaDoc;
36 import javax.jms.JMSSecurityException JavaDoc;
37
38 import org.apache.soap.Constants;
39 import org.apache.soap.Fault;
40 import org.apache.soap.SOAPException;
41 import org.apache.soap.encoding.SOAPMappingRegistry;
42 import org.apache.soap.encoding.soapenc.BeanSerializer;
43 import org.apache.soap.rpc.Call;
44 import org.apache.soap.rpc.Parameter;
45 import org.apache.soap.rpc.Response;
46 import org.apache.soap.util.xml.QName;
47
48 import org.objectweb.joram.client.jms.FactoryParameters;
49 import org.objectweb.joram.shared.client.*;
50 import org.objectweb.joram.client.jms.connection.RequestChannel;
51
52 import org.objectweb.joram.shared.JoramTracing;
53 import org.objectweb.util.monolog.api.BasicLevel;
54
55 /**
56  * A <code>SoapConnection</code> links a Joram client and a Joram platform
57  * with HTTP connections.
58  * <p>
59  * Requests and replies travel through the connections in SOAP (XML) format.
60  */

61 public class SoapConnection
62     implements RequestChannel {
63   /** The user's name */
64   private String JavaDoc name;
65   
66   private String JavaDoc password;
67   
68   private FactoryParameters factParams;
69
70   /** URL of the SOAP service this object communicates with. */
71   private URL JavaDoc serviceUrl = null;
72
73   /** SOAP call object for sending the requests. */
74   private Call sendCall;
75
76   private Call receiveCall;
77
78   /** Identifier of the connection. */
79   private int cnxId;
80
81   /**
82    * Creates a <code>SoapConnection</code> instance.
83    *
84    * @param params Factory parameters.
85    * @param name Name of user.
86    * @param password Password of user.
87    *
88    * @exception JMSSecurityException If the user identification is incorrrect.
89    * @exception IllegalStateException If the server is not reachable.
90    */

91   public SoapConnection(FactoryParameters factParams2,
92                         String JavaDoc name2,
93                         String JavaDoc password2) throws JMSException JavaDoc
94   {
95     factParams = factParams2;
96     name = name2;
97     password = password2;
98   }
99   
100   public void setTimer(Timer JavaDoc timer) {
101     // No timer is useful
102
}
103   
104   public void connect() throws Exception JavaDoc {
105     connect(factParams, name, password);
106
107     // Building the Call object for sending the requests:
108
SOAPMappingRegistry mappingReg = new SOAPMappingRegistry();
109     BeanSerializer beanSer = new BeanSerializer();
110
111     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
112                         new QName("urn:ProxyService", "AbstractJmsRequest"),
113                                   AbstractJmsRequest.class, beanSer, beanSer);
114     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
115                         new QName("urn:ProxyService", "CnxConnectRequest"),
116                                   CnxConnectRequest.class, beanSer, beanSer);
117     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
118                         new QName("urn:ProxyService", "CnxStartRequest"),
119                                   CnxStartRequest.class, beanSer, beanSer);
120     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
121                         new QName("urn:ProxyService", "CnxStopRequest"),
122                                   CnxStopRequest.class, beanSer, beanSer);
123     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
124                         new QName("urn:ProxyService", "CnxCloseRequest"),
125                                   CnxCloseRequest.class, beanSer, beanSer);
126     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
127                         new QName("urn:ProxyService", "ConsumerAckRequest"),
128                                   ConsumerAckRequest.class, beanSer, beanSer);
129     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
130                         new QName("urn:ProxyService", "ConsumerDenyRequest"),
131                                   ConsumerDenyRequest.class, beanSer, beanSer);
132     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
133                         new QName("urn:ProxyService",
134                                   "ConsumerReceiveRequest"),
135                                   ConsumerReceiveRequest.class, beanSer,
136                                   beanSer);
137     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
138                         new QName("urn:ProxyService",
139                                   "ConsumerSetListRequest"),
140                                   ConsumerSetListRequest.class, beanSer,
141                                   beanSer);
142     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
143                         new QName("urn:ProxyService",
144                                   "ConsumerUnsetListRequest"),
145                                   ConsumerUnsetListRequest.class, beanSer,
146                                   beanSer);
147     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
148                         new QName("urn:ProxyService", "ConsumerSubRequest"),
149                                   ConsumerSubRequest.class, beanSer, beanSer);
150     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
151                         new QName("urn:ProxyService", "ConsumerUnsubRequest"),
152                                   ConsumerUnsubRequest.class,
153                                   beanSer, beanSer);
154     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
155                         new QName("urn:ProxyService",
156                                   "ConsumerCloseSubRequest"),
157                                   ConsumerCloseSubRequest.class, beanSer,
158                                   beanSer);
159     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
160                         new QName("urn:ProxyService", "QBrowseRequest"),
161                                   QBrowseRequest.class, beanSer, beanSer);
162     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
163                         new QName("urn:ProxyService", "SessAckRequest"),
164                                   SessAckRequest.class, beanSer, beanSer);
165     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
166                         new QName("urn:ProxyService", "SessDenyRequest"),
167                                   SessDenyRequest.class, beanSer, beanSer);
168     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
169                         new QName("urn:ProxyService", "SessCreateTQRequest"),
170                                   SessCreateTQRequest.class, beanSer, beanSer);
171     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
172                         new QName("urn:ProxyService", "SessCreateTTRequest"),
173                                   SessCreateTTRequest.class, beanSer, beanSer);
174     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
175                         new QName("urn:ProxyService", "TempDestDeleteRequest"),
176                                   TempDestDeleteRequest.class, beanSer,
177                                   beanSer);
178     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
179                         new QName("urn:ProxyService", "GetAdminTopicRequest"),
180                                   GetAdminTopicRequest.class, beanSer,
181                                   beanSer);
182
183     sendCall = new Call();
184     sendCall.setSOAPMappingRegistry(mappingReg);
185     sendCall.setTargetObjectURI("urn:ProxyService");
186     sendCall.setMethodName("send");
187     sendCall.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
188
189     mappingReg = new SOAPMappingRegistry();
190     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
191                         new QName("urn:ProxyService", "AbstractJmsReply"),
192                                   AbstractJmsReply.class, beanSer, beanSer);
193     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
194                         new QName("urn:ProxyService", "CnxConnectReply"),
195                                   CnxConnectReply.class, beanSer, beanSer);
196     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
197                         new QName("urn:ProxyService", "ServerReply"),
198                                   ServerReply.class, beanSer, beanSer);
199     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
200                         new QName("urn:ProxyService", "SessCreateTDReply"),
201                                   SessCreateTDReply.class, beanSer, beanSer);
202     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
203                         new QName("urn:ProxyService", "CnxCloseReply"),
204                                   CnxCloseReply.class, beanSer, beanSer);
205     mappingReg.mapTypes(Constants.NS_URI_SOAP_ENC,
206                         new QName("urn:ProxyService", "GetAdminTopicReply"),
207                                   GetAdminTopicReply.class, beanSer, beanSer);
208
209     receiveCall = new Call();
210     receiveCall.setSOAPMappingRegistry(mappingReg);
211     receiveCall.setTargetObjectURI("urn:ProxyService");
212     receiveCall.setMethodName("getReply");
213     receiveCall.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
214   }
215
216   /**
217    * Sending a JMS request through the SOAP protocol.
218    *
219    * @exception IllegalStateException If the SOAP service fails.
220    */

221   public synchronized void send(AbstractJmsRequest request) throws Exception JavaDoc {
222     Hashtable JavaDoc h = request.soapCode();
223
224     // Setting the call's parameters:
225
Vector JavaDoc params = new Vector JavaDoc();
226     params.addElement(new Parameter("name", String JavaDoc.class, name, null));
227     params.add(new Parameter("cnxId", Integer JavaDoc.class,
228                              new Integer JavaDoc(cnxId), null));
229     params.add(new Parameter("map", Hashtable JavaDoc.class, h, null));
230     sendCall.setParams(params);
231
232     // Sending the request, checking the reply:
233
try {
234       Response resp = sendCall.invoke(serviceUrl,"");
235
236       // Check the response.
237
if (resp.generatedFault ()) {
238         throw new IllegalStateException JavaDoc("The SOAP service failed to process"
239                                         + " the call: "
240                                         + resp.getFault().getFaultString());
241       }
242     } catch (SOAPException exc) {
243       throw new IllegalStateException JavaDoc("The SOAP call failed: "
244                                       + exc.getMessage());
245     }
246   }
247
248   /** Closes the <code>SoapConnection</code>. */
249   public void close() {}
250
251   /**
252    * Actually tries to set a first SOAP connection with the server.
253    *
254    * @param params Factory parameters.
255    * @param name The user's name.
256    * @param password The user's password.
257    *
258    * @exception JMSSecurityException If the user identification is incorrrect.
259    * @exception IllegalStateException If the SOAP service fails.
260    */

261   private void connect(FactoryParameters factParams, String JavaDoc name,
262                        String JavaDoc password) throws JMSException JavaDoc {
263     // Setting the timer values:
264
long startTime = System.currentTimeMillis();
265     long endTime = startTime + factParams.connectingTimer * 1000;
266     long currentTime;
267     long nextSleep = 2000;
268     boolean tryAgain;
269     int attemptsC = 0;
270     Response resp;
271     String JavaDoc error;
272
273     try {
274       serviceUrl = new URL JavaDoc("http://"
275                            + factParams.getHost()
276                            + ":"
277                            + factParams.getPort()
278                            + "/soap/servlet/rpcrouter");
279     }
280     catch (MalformedURLException JavaDoc exc) {}
281
282     // Building the Call object for checking the user's identification:
283
Call checkCall = new Call();
284     checkCall.setTargetObjectURI("urn:ProxyService");
285     checkCall.setMethodName("setConnection");
286     checkCall.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
287
288     Vector JavaDoc params = new Vector JavaDoc();
289     params.addElement(new Parameter("name", String JavaDoc.class, name, null));
290     params.addElement(new Parameter("password", String JavaDoc.class, password, null));
291     params.addElement(new Parameter("timeout",
292                                     Integer JavaDoc.class,
293                                     new Integer JavaDoc(factParams.cnxPendingTimer),
294                                     null));
295
296     checkCall.setParams(params);
297
298     while (true) {
299       tryAgain = false;
300       attemptsC++;
301       error = null;
302
303       try {
304         resp = checkCall.invoke(serviceUrl,"");
305
306         // SOAP sends a fault back: the service is possibly not started or
307
// not running.
308
if (resp.generatedFault ()) {
309           error = resp.getFault().getFaultString();
310           tryAgain = true;
311         }
312         // RPC call worked:
313
else {
314           Integer JavaDoc result = (Integer JavaDoc) resp.getReturnValue().getValue();
315
316           // The returned value is either the key of the connection, or -1
317
// if the user is invalid:
318
if (result.intValue() == -1) {
319             throw new JMSSecurityException JavaDoc("Can't open the connection with"
320                                            + " the server on host "
321                                            + factParams.getHost()
322                                            + " and port "
323                                            + factParams.getPort()
324                                            + ": invalid user identification.");
325           }
326           cnxId = result.intValue();
327           break;
328         }
329       }
330       // SOAP call failed: the server may not be started.
331
catch (SOAPException exc) {
332         tryAgain = true;
333         error = exc.getMessage();
334       }
335       // Trying again to connect:
336
if (tryAgain) {
337         currentTime = System.currentTimeMillis();
338         // Keep on trying as long as timer is ok:
339
if (currentTime < endTime) {
340
341           if (currentTime + nextSleep > endTime)
342             nextSleep = endTime - currentTime;
343
344           // Sleeping for a while:
345
try {
346             Thread.sleep(nextSleep);
347           }
348           catch (InterruptedException JavaDoc intExc) {}
349
350           // Trying again!
351
nextSleep = nextSleep * 2;
352           continue;
353         }
354         // If timer is over, throwing an IllegalStateException:
355
else {
356           long attemptsT = (System.currentTimeMillis() - startTime) / 1000;
357           throw new IllegalStateException JavaDoc("Could not open the connection"
358                                           + " with server on host "
359                                           + factParams.getHost()
360                                           + " and port "
361                                           + factParams.getPort()
362                                           + " after " + attemptsC
363                                           + " attempts during "
364                                           + attemptsT + " secs: "
365                                           + error);
366         }
367       }
368     }
369   }
370
371   public AbstractJmsReply receive() throws Exception JavaDoc {
372     Vector JavaDoc params = new Vector JavaDoc();
373     params.addElement(new Parameter("name", String JavaDoc.class, name, null));
374     params.addElement(new Parameter("cnxId", int.class, new Integer JavaDoc(cnxId), null));
375     receiveCall.setParams(params);
376     
377     Response resp = null;
378     AbstractJmsReply reply = null;
379     
380     try {
381       resp = receiveCall.invoke(serviceUrl, "");
382     } catch (SOAPException exc) {
383       throw new IOException JavaDoc("The SOAP call failed: " + exc.getMessage());
384     }
385
386     if (resp.generatedFault()) {
387       throw new IOException JavaDoc("The SOAP service failed to process the call: "
388                             + resp.getFault().getFaultString());
389     }
390     
391     try {
392       Hashtable JavaDoc h = (Hashtable JavaDoc) resp.getReturnValue().getValue();
393       reply = (AbstractJmsReply) AbstractJmsMessage.soapDecode(h);
394     } catch (Exception JavaDoc exc) {
395       throw new IOException JavaDoc(exc.getMessage());
396     }
397
398     return reply;
399   }
400 }
401
Popular Tags