KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > joram > client > connector > ManagedConnectionFactoryImpl


1 /*
2  * JORAM: Java(TM) Open Reliable Asynchronous Messaging
3  * Copyright (C) 2004 - 2006 ScalAgent Distributed Technologies
4  * Copyright (C) 2004 - 2006 Bull SA
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 (Bull SA)
22  * Contributor(s): ScalAgent Distributed Technologies
23  * Benoit Pelletier (Bull SA)
24  */

25 package org.objectweb.joram.client.connector;
26
27 import org.objectweb.joram.client.jms.FactoryParameters;
28 import org.objectweb.joram.client.jms.ha.local.XAHALocalConnectionFactory;
29 import org.objectweb.joram.client.jms.ha.tcp.HATcpConnectionFactory;
30 import org.objectweb.joram.client.jms.ha.tcp.XAHATcpConnectionFactory;
31 import org.objectweb.joram.client.jms.local.XALocalConnectionFactory;
32 import org.objectweb.joram.client.jms.tcp.TcpConnectionFactory;
33 import org.objectweb.joram.client.jms.tcp.XATcpConnectionFactory;
34
35 import javax.jms.ConnectionFactory JavaDoc;
36 import javax.jms.JMSException JavaDoc;
37 import javax.jms.JMSSecurityException JavaDoc;
38 import javax.jms.IllegalStateException JavaDoc;
39 import javax.jms.XAConnection JavaDoc;
40 import javax.jms.XAConnectionFactory JavaDoc;
41 import javax.jms.XAQueueConnection JavaDoc;
42 import javax.jms.XATopicConnection JavaDoc;
43 import javax.naming.StringRefAddr JavaDoc;
44 import javax.naming.Reference JavaDoc;
45 import javax.resource.ResourceException JavaDoc;
46 import javax.resource.spi.CommException JavaDoc;
47 import javax.resource.spi.ConnectionManager JavaDoc;
48 import javax.resource.spi.ConnectionRequestInfo JavaDoc;
49 import javax.resource.spi.ManagedConnection JavaDoc;
50 import javax.resource.spi.ResourceAdapter JavaDoc;
51 import javax.resource.spi.SecurityException JavaDoc;
52 import javax.security.auth.Subject JavaDoc;
53
54 import java.io.PrintWriter JavaDoc;
55 import java.util.Iterator JavaDoc;
56 import java.util.Set JavaDoc;
57 import java.util.Vector JavaDoc;
58
59 import org.objectweb.util.monolog.api.BasicLevel;
60
61 /**
62  * A <code>ManagedConnectionFactoryImpl</code> instance manages
63  * outbound connectivity to a given JORAM server.
64  */

65 public class ManagedConnectionFactoryImpl
66              implements javax.resource.spi.ManagedConnectionFactory JavaDoc,
67                         javax.resource.spi.ResourceAdapterAssociation JavaDoc,
68                         javax.resource.spi.ValidatingManagedConnectionFactory JavaDoc,
69                         java.io.Serializable JavaDoc
70 {
71   /** Vector of managed connections. */
72   private transient Vector JavaDoc connections = null;
73   /** Out stream for error logging and tracing. */
74   protected transient PrintWriter JavaDoc out = null;
75
76   /** Resource adapter central authority. */
77   transient JoramAdapter ra = null;
78
79   /** <code>true</code> for collocated outbound connectivity. */
80   boolean collocated;
81
82   /** <code>true</code> for ha mode */
83   boolean isHa;
84
85   /** Underlying JORAM server host name. */
86   String JavaDoc hostName;
87   /** Underlying JORAM server port number. */
88   int serverPort;
89
90   /** Default user identification. */
91   String JavaDoc userName = "anonymous";
92   /** Default user password. */
93   String JavaDoc password = "anonymous";
94
95   /**
96    * Duration in seconds during which connecting is attempted (connecting
97    * might take time if the server is temporarily not reachable); the 0 value
98    * is set for connecting only once and aborting if connecting failed.
99    */

100   public int connectingTimer = 0;
101   /**
102    * Duration in seconds during which a JMS transacted (non XA) session might
103    * be pending; above that duration the session is rolled back and closed;
104    * the 0 value means "no timer".
105    */

106   public int txPendingTimer = 0;
107   /**
108    * Period in milliseconds between two ping requests sent by the client
109    * connection to the server; if the server does not receive any ping
110    * request during more than 2 * cnxPendingTimer, the connection is
111    * considered as dead and processed as required.
112    */

113   public int cnxPendingTimer = 0;
114
115   /**
116    * Determines whether the produced messages are asynchronously
117    * sent or not (without or with acknowledgement)
118    * Default is false (with ack).
119    */

120   public boolean asyncSend;
121
122   /**
123    * Determines whether client threads
124    * which are using the same connection
125    * are synchronized
126    * in order to group together the requests they
127    * send.
128    */

129   public boolean multiThreadSync;
130
131   /**
132    * The maximum time the threads hang if 'multiThreadSync' is true.
133    * Either they wake up (wait time out) or they are notified (by the
134    * first woken up thread).
135    *
136    */

137   public int multiThreadSyncDelay = -1;
138
139   /**
140    * Constructs a <code>ManagedConnectionFactoryImpl</code> instance.
141    */

142   public ManagedConnectionFactoryImpl()
143   {}
144
145   public int getConnectingTimer() {
146     return connectingTimer;
147   }
148
149   public int getCnxPendingTimer() {
150     return cnxPendingTimer;
151   }
152
153   public int getTxPendingTimer() {
154     return txPendingTimer;
155   }
156
157   protected void setParameters(Object JavaDoc factory) {
158     FactoryParameters fp = null;
159     if (factory instanceof org.objectweb.joram.client.jms.ConnectionFactory) {
160       org.objectweb.joram.client.jms.ConnectionFactory f =
161         (org.objectweb.joram.client.jms.ConnectionFactory) factory;
162       fp = f.getParameters();
163     } else if (factory instanceof org.objectweb.joram.client.jms.XAConnectionFactory) {
164       org.objectweb.joram.client.jms.XAConnectionFactory f =
165         (org.objectweb.joram.client.jms.XAConnectionFactory) factory;
166       fp = f.getParameters();
167     }
168     if (fp != null) {
169       fp.connectingTimer = connectingTimer;
170       fp.cnxPendingTimer = cnxPendingTimer;
171       fp.txPendingTimer = txPendingTimer;
172       if (asyncSend) {
173         fp.asyncSend = asyncSend;
174       }
175       if (multiThreadSync) {
176         fp.multiThreadSync = multiThreadSync;
177       }
178       if (multiThreadSyncDelay > 0) {
179         fp.multiThreadSyncDelay = multiThreadSyncDelay;
180       }
181     }
182   }
183
184   /**
185    * Method called by an application server (managed case) for creating an
186    * <code>OutboundConnectionFactory</code> instance.
187    *
188    * @param cxManager Application server's connections pooling manager.
189    *
190    * @exception ResourceException Never thrown.
191    */

192   public Object JavaDoc createConnectionFactory(ConnectionManager JavaDoc cxManager)
193     throws ResourceException JavaDoc {
194     if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
195       AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG, this + " createConnectionFactory(" + cxManager + ")");
196
197     return new OutboundConnectionFactory(this, cxManager);
198   }
199
200   /**
201    * Method called in the non managed case for creating an
202    * <code>OutboundConnectionFactory</code> instance.
203    *
204    * @exception ResourceException Never thrown.
205    */

206   public Object JavaDoc createConnectionFactory() throws ResourceException JavaDoc {
207     if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
208       AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG, this + " createConnectionFactory()");
209
210     OutboundConnectionFactory factory =
211       new OutboundConnectionFactory(this, null);
212
213     Reference JavaDoc ref =
214       new Reference JavaDoc(factory.getClass().getName(),
215                     "org.objectweb.joram.client.connector.ObjectFactoryImpl",
216                     null);
217     ref.add(new StringRefAddr JavaDoc("hostName", hostName));
218     ref.add(new StringRefAddr JavaDoc("serverPort", "" + serverPort));
219     ref.add(new StringRefAddr JavaDoc("userName", userName));
220     ref.add(new StringRefAddr JavaDoc("password", password));
221
222     factory.setReference(ref);
223     return factory;
224   }
225
226   /**
227    * Creates a new physical connection to the underlying JORAM server,
228    * and returns a <code>ManagedConnectionImpl</code> instance for a
229    * managed environment.
230    *
231    * @param subject Security data, not taken into account.
232    * @param cxRequest User identification data, may be <code>null</code>.
233    *
234    * @exception CommException If the JORAM server is not reachable.
235    * @exception SecurityException If the connecting is not allowed.
236    * @exception IllegalStateException If the central Joram adapter state is
237    * invalid.
238    * @exception ResourceException If the provided user info is invalid,
239    * or if connecting fails for any other
240    * reason.
241    */

242   public ManagedConnection JavaDoc
243       createManagedConnection(Subject JavaDoc subject,
244                               ConnectionRequestInfo JavaDoc cxRequest)
245     throws ResourceException JavaDoc {
246     if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
247       AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG,
248                                     this + " createManagedConnection(" + subject +
249                                     ", " + cxRequest + ")");
250
251     String JavaDoc userName;
252     String JavaDoc password;
253
254     String JavaDoc hostName = this.hostName;
255     int serverPort = this.serverPort;
256
257     // For XA recovery, connecting to the JORAM server with the default user
258
// identity.
259
if (cxRequest == null) {
260       userName = this.userName;
261       password = this.password;
262     }
263     else {
264       if (! (cxRequest instanceof ConnectionRequest)) {
265         if (out != null)
266             out.print("Provided ConnectionRequestInfo instance is not a JORAM object.");
267         throw new ResourceException JavaDoc("Provided ConnectionRequestInfo instance "
268                                     + "is not a JORAM object.");
269       }
270
271       userName = ((ConnectionRequest) cxRequest).getUserName();
272       password = ((ConnectionRequest) cxRequest).getPassword();
273     }
274
275     XAConnectionFactory JavaDoc factory;
276     XAConnection JavaDoc cnx = null;
277
278     if (collocated) {
279         hostName = "localhost";
280         serverPort = -1;
281     }
282
283     if (isHa) {
284         if (collocated) {
285             factory = XAHALocalConnectionFactory.create();
286         } else {
287             String JavaDoc urlHa = "hajoram://" + hostName + ":" + serverPort;
288             factory = XAHATcpConnectionFactory.create(urlHa);
289         }
290     } else {
291         if (collocated) {
292             factory = XALocalConnectionFactory.create();
293         } else {
294             factory = XATcpConnectionFactory.create(hostName, serverPort);
295         }
296     }
297
298     setParameters(factory);
299
300     try {
301       cnx = factory.createXAConnection(userName, password);
302
303       if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
304         AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG,
305                                       this + " createManagedConnection cnx = " + cnx);
306     } catch (IllegalStateException JavaDoc exc) {
307       if (out != null)
308           out.print("Could not access the JORAM server: " + exc);
309       throw new CommException JavaDoc("Could not access the JORAM server: " + exc);
310     } catch (JMSSecurityException JavaDoc exc) {
311         if (out != null)
312             out.print("Invalid user identification: " + exc);
313       throw new SecurityException JavaDoc("Invalid user identification: " + exc);
314     } catch (JMSException JavaDoc exc) {
315         if (out != null)
316             out.print("Failed connecting process: " + exc);
317       throw new ResourceException JavaDoc("Failed connecting process: " + exc);
318     }
319
320     ManagedConnection JavaDoc managedCx = new ManagedConnectionImpl(ra,
321                                                             cnx,
322                                                             hostName,
323                                                             serverPort,
324                                                             userName);
325     managedCx.setLogWriter(out);
326
327     if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
328       AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG,
329                                     this + " createManagedConnection managedCx = " + managedCx);
330     return managedCx;
331   }
332
333   /**
334    * Finds a matching connection from the candidate set of connections and
335    * returns a <code>ManagedConnectionImpl</code> instance.
336    *
337    * @param connectionSet Set of connections to test.
338    * @param subject Security data, not taken into account.
339    * @param cxRequest User identification data, may be <code>null</code>.
340    *
341    * @exception ResourceException If the provided connection request info is
342    * invalid.
343    */

344   public ManagedConnection JavaDoc
345       matchManagedConnections(Set JavaDoc connectionSet,
346                               Subject JavaDoc subject,
347                               ConnectionRequestInfo JavaDoc cxRequest)
348     throws ResourceException JavaDoc {
349     if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
350       AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG,
351                                     this + " matchManagedConnections(" + connectionSet +
352                                     ", " + subject + ", " + cxRequest + ")");
353
354     String JavaDoc userName;
355
356     // No user identification provided, using the default one.
357
String JavaDoc mode = "Unified";
358
359     if (cxRequest == null)
360       userName = this.userName;
361     else {
362       if (! (cxRequest instanceof ConnectionRequest)) {
363         out.print("Provided ConnectionRequestInfo instance is not a JORAM object.");
364         throw new ResourceException JavaDoc("Provided ConnectionRequestInfo instance "
365                                     + "is not a JORAM object.");
366       }
367
368       if (cxRequest instanceof QueueConnectionRequest)
369           mode = "PTP";
370       else if (cxRequest instanceof TopicConnectionRequest)
371           mode = "PubSub";
372
373       userName = ((ConnectionRequest) cxRequest).getUserName();
374     }
375
376     ManagedConnectionImpl managedCx = null;
377     boolean matching = false;
378
379     Iterator JavaDoc it = connectionSet.iterator();
380
381     String JavaDoc hostName = this.hostName;
382     int serverPort = this.serverPort;
383
384     if (collocated) {
385         hostName = "localhost";
386         serverPort = -1;
387     }
388
389
390     while (! matching && it.hasNext()) {
391       try {
392         managedCx = (ManagedConnectionImpl) it.next();
393
394         matching =
395           managedCx.matches(hostName, serverPort, userName, mode);
396       }
397       catch (ClassCastException JavaDoc exc) {
398       }
399     }
400
401     if (matching) {
402       if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
403         AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG,
404                                       this + " matchManagedConnections managedCx = " + managedCx);
405       managedCx.setLogWriter(out);
406       return managedCx;
407     }
408
409     return null;
410   }
411
412
413
414   /**
415    * Sets the log writer for this <code>ManagedConnectionFactoryImpl</code>
416    * instance.
417    */

418   public void setLogWriter(PrintWriter JavaDoc out) throws ResourceException JavaDoc
419   {
420     this.out = out;
421   }
422
423   /**
424    * Gets the log writer of this <code>ManagedConnectionFactoryImpl</code>
425    * instance.
426    */

427   public PrintWriter JavaDoc getLogWriter() throws ResourceException JavaDoc
428   {
429     return out;
430   }
431
432   /** Returns a code depending on the managed factory configuration. */
433   public int hashCode()
434   {
435     return ("Unified:"
436             + hostName
437             + ":"
438             + serverPort
439             + "-"
440             + userName).hashCode();
441   }
442
443   /** Compares managed factories according to their configuration. */
444   public boolean equals(Object JavaDoc o)
445   {
446     if (! (o instanceof ManagedConnectionFactoryImpl)
447         || o instanceof ManagedQueueConnectionFactoryImpl
448         || o instanceof ManagedTopicConnectionFactoryImpl)
449       return false;
450
451     ManagedConnectionFactoryImpl other = (ManagedConnectionFactoryImpl) o;
452
453     boolean res =
454       hostName.equals(other.hostName)
455       && serverPort == other.serverPort
456       && userName.equals(other.userName);
457
458     if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
459       AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG,
460                                     this + " equals " + res);
461     return res;
462   }
463
464   /** Returns the resource adapter central authority instance. */
465   public ResourceAdapter JavaDoc getResourceAdapter() {
466     if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
467       AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG,
468                                     this + " getResourceAdapter() = " + ra);
469     return ra;
470   }
471
472   /**
473    * Sets the resource adapter central authority.
474    *
475    * @exception ResourceException If the adapter could not be set.
476    */

477   public void setResourceAdapter(ResourceAdapter JavaDoc ra)
478     throws ResourceException JavaDoc {
479     if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
480       AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG,
481                                     this + " setResourceAdapter(" + ra + ")");
482
483     if (this.ra != null) {
484       out.print("ResourceAdapter instance already associated.");
485       throw new javax.resource.spi.IllegalStateException JavaDoc("ResourceAdapter "
486                                                          + "instance "
487                                                          + "already "
488                                                          + "associated.");
489     }
490
491     if (! (ra instanceof JoramAdapter)) {
492       out.print("Provided ResourceAdapter is not a JORAM ResourceAdapter object: "
493                 + ra.getClass().getName());
494       throw new ResourceException JavaDoc("Provided ResourceAdapter is not a JORAM "
495                                   + "ResourceAdapter object: "
496                                   + ra.getClass().getName());
497     }
498
499     this.ra = (JoramAdapter) ra;
500     collocated = ((JoramAdapter) ra).collocated;
501     isHa = ((JoramAdapter) ra).isHa;
502     hostName = ((JoramAdapter) ra).hostName;
503     serverPort = ((JoramAdapter) ra).serverPort;
504     connectingTimer = ((JoramAdapter) ra).connectingTimer;
505     txPendingTimer = ((JoramAdapter) ra).txPendingTimer;
506     cnxPendingTimer = ((JoramAdapter) ra).cnxPendingTimer;
507     asyncSend = ((JoramAdapter) ra).asyncSend;
508     multiThreadSync = ((JoramAdapter) ra).multiThreadSync;
509     multiThreadSyncDelay = ((JoramAdapter) ra).multiThreadSyncDelay;
510
511     if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
512       AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG,
513                                     this + " setResourceAdapter collocated = " + collocated +
514                                     ", isHa = " + isHa +
515                                     ", hostName = " + hostName +
516                                     ", serverPort = " + serverPort +
517                                     ", connectingTimer = " + connectingTimer +
518                                     ", txPendingTimer = " + txPendingTimer +
519                                     ", cnxPendingTimer = " + cnxPendingTimer);
520   }
521
522   /**
523    * From a set of managed connections, returns the set of invalid ones.
524    */

525   public Set JavaDoc getInvalidConnections(Set JavaDoc connectionSet)
526     throws ResourceException JavaDoc {
527     if (AdapterTracing.dbgAdapter.isLoggable(BasicLevel.DEBUG))
528       AdapterTracing.dbgAdapter.log(BasicLevel.DEBUG,
529                                     this + " getInvalidConnections(" + connectionSet + ")");
530
531     Iterator JavaDoc it = connectionSet.iterator();
532     ManagedConnectionImpl managedCx;
533
534     while (it.hasNext()) {
535       try {
536         managedCx = (ManagedConnectionImpl) it.next();
537         if (managedCx.isValid())
538           connectionSet.remove(managedCx);
539       }
540       catch (ClassCastException JavaDoc exc) {}
541     }
542
543     return connectionSet;
544   }
545
546   /** Deserializing method. */
547   private void readObject(java.io.ObjectInputStream JavaDoc in)
548           throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc
549   {
550     in.defaultReadObject();
551     connections = new Vector JavaDoc();
552   }
553
554   // ------------------------------------------
555
// --- JavaBean setter and getter methods ---
556
// ------------------------------------------
557

558   public void setCollocated(java.lang.Boolean JavaDoc collocated)
559   {
560     this.collocated = collocated.booleanValue();
561   }
562
563   public void setHostName(java.lang.String JavaDoc hostName)
564   {
565     this.hostName = hostName;
566   }
567
568   public void setServerPort(java.lang.Integer JavaDoc serverPort)
569   {
570     this.serverPort = serverPort.intValue();
571   }
572
573   public void setUserName(java.lang.String JavaDoc userName)
574   {
575     this.userName = userName;
576   }
577
578   public void setPassword(java.lang.String JavaDoc password)
579   {
580     this.password = password;
581   }
582
583   public java.lang.Boolean JavaDoc getCollocated()
584   {
585     return new Boolean JavaDoc(collocated);
586   }
587
588   public java.lang.String JavaDoc getHostName()
589   {
590     return hostName;
591   }
592
593   public java.lang.Integer JavaDoc getServerPort()
594   {
595     return new Integer JavaDoc(serverPort);
596   }
597
598   public java.lang.String JavaDoc getUserName()
599   {
600     return userName;
601   }
602
603   public java.lang.String JavaDoc getPassword()
604   {
605     return password;
606   }
607 }
608
Popular Tags