KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > connectors > ConnectionManagerImpl


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.connectors;
24
25 import java.io.Serializable JavaDoc;
26 import java.security.AccessController JavaDoc;
27 import java.security.PrivilegedAction JavaDoc;
28 import java.security.Principal JavaDoc;
29 import java.util.Properties JavaDoc;
30 import javax.resource.ResourceException JavaDoc;
31 import javax.resource.spi.*;
32 import javax.resource.spi.IllegalStateException JavaDoc;
33 import javax.resource.NotSupportedException JavaDoc;
34 import com.sun.enterprise.*;
35 import com.sun.enterprise.security.SecurityContext;
36 import com.sun.enterprise.util.i18n.StringManager;
37 import com.sun.enterprise.deployment.ResourceReferenceDescriptor;
38 import com.sun.enterprise.deployment.ConnectorDescriptor;
39 import com.sun.enterprise.connectors.ConnectorConnectionPool;
40 import com.sun.enterprise.connectors.ConnectorDescriptorInfo;
41 import com.sun.enterprise.connectors.authentication.AuthenticationService;
42 import com.sun.enterprise.deployment.ResourcePrincipal;
43 import com.sun.enterprise.distributedtx.J2EETransactionManagerOpt;
44 import com.sun.enterprise.naming.NamingManagerImpl;
45 import com.sun.enterprise.log.Log;
46 import com.sun.enterprise.iiop.PEORBConfigurator;
47 import com.sun.enterprise.resource.*;
48 import javax.security.auth.Subject JavaDoc;
49 import javax.naming.InitialContext JavaDoc;
50 import javax.resource.spi.security.PasswordCredential JavaDoc;
51 import java.util.logging.*;
52 import java.util.Set JavaDoc;
53 import com.sun.logging.*;
54 import com.sun.enterprise.connectors.util.ConnectionPoolObjectsUtils;
55
56 /**
57  * @author Tony Ng
58  */

59 public class ConnectionManagerImpl
60     implements ConnectionManager, Serializable JavaDoc {
61     
62     protected String JavaDoc jndiName;
63     
64     protected String JavaDoc poolName;
65
66     // Create logger object per Java SDK 1.4 to log messages
67
// introduced Santanu De, Sun Microsystems, March 2002
68

69     static Logger _logger = LogDomains.getLogger(LogDomains.RSR_LOGGER);
70
71     //The RAR name
72
//This is pushed into the object in the connector runtime during
73
//jndi publishing
74
protected String JavaDoc rarName;
75
76     protected ResourcePrincipal defaultPrin = null;
77
78     public ConnectionManagerImpl(String JavaDoc poolName) {
79         this.poolName = poolName;
80     }
81
82     public void setJndiName(String JavaDoc jndiName) {
83         this.jndiName = jndiName;
84     }
85     
86     public String JavaDoc getJndiName() {
87         return jndiName;
88     }
89     
90     public void setPoolName(String JavaDoc poolName) {
91         this.poolName = poolName;
92     }
93
94     /**
95      * Allocate a non transactional connection. This connection, even if
96      * acquired in the context of an existing transaction, will never
97      * be associated with a transaction
98      * The typical use case may be to check the original contents of an EIS
99      * when a transacted connection is changing the contents, and the tx
100      * is yet to be committed.
101      *
102      * We create a ResourceSpec for a non tx connection with a name ending
103      * in __nontx. This is to maintain uniformity with the scheme of having
104      * __pm connections.
105      * If one were to create a resource with a jndiName ending with __nontx
106      * the same functionality might be achieved.
107      */

108     public Object JavaDoc allocateNonTxConnection( ManagedConnectionFactory mcf,
109         ConnectionRequestInfo cxRequestInfo ) throws ResourceException JavaDoc
110     {
111         String JavaDoc localJndiName = jndiName;
112
113     if (_logger.isLoggable(Level.FINE)) {
114         _logger.fine("Allocating NonTxConnection");
115     }
116
117     //If a resource has been created with __nontx, we don't want to
118
//add it again.
119
//Otherwise we need to add __nontx at the end to ensure that the
120
//mechanism to check for the correct resource manager still works
121
//We do the addition if and only if we are getting this call
122
//from a normal datasource and not a __nontx datasource.
123
if ( ! jndiName.endsWith( ConnectorConstants.NON_TX_JNDI_SUFFIX ) ) {
124         localJndiName = jndiName + ConnectorConstants.NON_TX_JNDI_SUFFIX ;
125         
126         if (_logger.isLoggable(Level.FINE)) {
127             _logger.fine("Adding __nontx to jndiname");
128         }
129     } else {
130         if (_logger.isLoggable(Level.FINE)) {
131             _logger.fine("lookup happened from a __nontx datasource directly");
132         }
133     }
134
135         return allocateConnection( mcf, cxRequestInfo, localJndiName);
136
137
138     }
139     
140     public Object JavaDoc
141         allocateConnection(ManagedConnectionFactory mcf,
142                            ConnectionRequestInfo cxRequestInfo)
143         throws ResourceException JavaDoc {
144
145         return this.allocateConnection( mcf, cxRequestInfo, jndiName);
146     }
147
148     public Object JavaDoc allocateConnection(ManagedConnectionFactory mcf,
149         ConnectionRequestInfo cxRequestInfo, String JavaDoc jndiNameToUse)
150         throws ResourceException JavaDoc
151     {
152         return this.allocateConnection( mcf, cxRequestInfo, jndiNameToUse, null );
153     }
154
155     public Object JavaDoc allocateConnection(ManagedConnectionFactory mcf,
156         ConnectionRequestInfo cxRequestInfo, String JavaDoc jndiNameToUse, Object JavaDoc conn)
157         throws ResourceException JavaDoc
158     {
159         validatePool();
160         PoolManager poolmgr = Switch.getSwitch().getPoolManager();
161     boolean resourceShareable = true;
162
163     ResourceReferenceDescriptor ref = poolmgr.getResourceReference(jndiNameToUse);
164     if (ref != null) {
165         String JavaDoc shareableStr = ref.getSharingScope();
166
167         // MQ resource adapter doesnt support connection sharing. Disabling it
168
// for the moment.
169
if (shareableStr.equals(ref.RESOURCE_UNSHAREABLE)) {
170                 resourceShareable = false;
171             }
172         }
173
174         if (ref == null) {
175             _logger.log(Level.FINE,"poolmgr.no_resource_reference",jndiNameToUse);
176             return internalGetConnection(mcf, defaultPrin, cxRequestInfo,
177                 resourceShareable, jndiNameToUse, conn, true);
178         }
179         String JavaDoc auth = ref.getAuthorization();
180     
181         if (auth.equals(ref.APPLICATION_AUTHORIZATION) ) {
182         if (cxRequestInfo == null ) {
183                 StringManager localStrings =
184                     StringManager.getManager(ConnectionManagerImpl.class);
185             String JavaDoc msg = localStrings.getString(
186             "con_mgr.null_userpass");
187             throw new ResourceException JavaDoc( msg );
188         }
189             ConnectorRuntime.getRuntime().switchOnMatching(rarName, poolName);
190             return internalGetConnection(mcf, null, cxRequestInfo,
191                 resourceShareable, jndiNameToUse, conn, false );
192         } else {
193             ResourcePrincipal prin =null;
194             Set JavaDoc principalSet =null;
195             Principal JavaDoc callerPrincipal = null;
196             SecurityContext securityContext = null;
197             ConnectorRuntime connectorRuntime = ConnectorRuntime.getRuntime();
198             if(connectorRuntime.isServer() &&
199              (securityContext = SecurityContext.getCurrent()) != null &&
200          (callerPrincipal = securityContext.getCallerPrincipal()) != null &&
201          (principalSet = securityContext.getPrincipalSet()) != null) {
202                 AuthenticationService authService =
203                     connectorRuntime.getAuthenticationService(rarName,poolName);
204                 if(authService != null) {
205                     prin = (ResourcePrincipal)authService.mapPrincipal(
206                             callerPrincipal, principalSet);
207                 }
208             }
209             
210             if (prin == null) {
211                 prin = ref.getResourcePrincipal();
212                 if (prin == null) {
213                     _logger.log(Level.FINE,"default-resource-principal not" +
214                         "specified for " + jndiNameToUse + ". Defaulting to" +
215                 " user/password specified in the pool");
216
217                     prin = defaultPrin;
218                 } else if (!prin.equals(defaultPrin)){
219                     ConnectorRuntime.getRuntime().switchOnMatching(rarName, poolName);
220                 }
221             }
222             return internalGetConnection(mcf, prin, cxRequestInfo,
223                 resourceShareable, jndiNameToUse, conn, false);
224         }
225    
226     }
227
228
229     protected Object JavaDoc internalGetConnection(ManagedConnectionFactory mcf,
230         final ResourcePrincipal prin, ConnectionRequestInfo cxRequestInfo,
231         boolean shareable, String JavaDoc jndiNameToUse, Object JavaDoc conn, boolean isUnknownAuth)
232         throws ResourceException JavaDoc
233     {
234         try {
235             PoolManager poolmgr = Switch.getSwitch().getPoolManager();
236         ConnectorRegistry registry = ConnectorRegistry.getInstance();
237             PoolMetaData pmd = registry.getPoolMetaData( poolName );
238             
239             ResourceSpec spec = new ResourceSpec(jndiNameToUse,
240                     ResourceSpec.JNDI_NAME, pmd);
241         spec.setConnectionPoolName(this.poolName);
242         ManagedConnectionFactory freshMCF = pmd.getMCF();
243
244         if (! freshMCF.equals(mcf)) {
245             _logger.log(Level.INFO, "conmgr.mcf_not_equal");
246         }
247             ConnectorDescriptor desc = registry.getDescriptor(rarName);
248
249             Subject JavaDoc subject = null;
250             ClientSecurityInfo info = null;
251             boolean subjectDefined = false;
252             if (isUnknownAuth && rarName.equals(ConnectorConstants.DEFAULT_JMS_ADAPTER)
253                   && !(pmd.isAuthCredentialsDefinedInPool())) {
254                  //System.out.println("Unkown Auth - pobably nonACC client");
255
//Unknown authorization. This is the case for standalone java clients,
256
//where the authorization is neither container nor component
257
//managed. In this case we associate an non-null Subject with no
258
//credentials, so that the RA can either use its own custom logic
259
//for figuring out the credentials. Relevant connector spec section
260
//is 9.1.8.2.
261
//create non-null Subject associated with no credentials
262
//System.out.println("RAR name "+ rarName);
263
subject = ConnectionPoolObjectsUtils.createSubject(mcf, null);
264             } else {
265                 if (prin == null) {
266                     info = new ClientSecurityInfo(cxRequestInfo);
267                 } else {
268                     info = new ClientSecurityInfo(prin);
269                     //If subject is defined, don't attempt to redefine it
270
if (subject == null) {
271                         if (prin.equals(defaultPrin)) {
272                            subject = pmd.getSubject();
273                         } else {
274                            subject = ConnectionPoolObjectsUtils.createSubject(mcf, prin);
275                         }
276                     }
277                 }
278             }
279
280         int txLevel = pmd.getTransactionSupport();
281         if (_logger.isLoggable(Level.FINE)) {
282             _logger.fine( "ConnectionMgr: poolName " + poolName +
283             " txLevel : " + txLevel );
284         }
285             
286             ResourceAllocator alloc = null;
287             if ( conn != null ) {
288                 spec.setConnectionToAssociate( conn );
289             }
290             
291             switch (txLevel) {
292             
293             case ConnectorConstants.NO_TRANSACTION_INT:
294                 alloc =
295                     new NoTxConnectorAllocator(poolmgr, mcf, spec,
296                                                subject, cxRequestInfo, info,
297                                                desc);
298                 return poolmgr.getResource(spec, alloc, info);
299                 
300             case ConnectorConstants.LOCAL_TRANSACTION_INT:
301                 if (!shareable) {
302                     StringManager localStrings =
303                         StringManager.getManager(ConnectionManagerImpl.class);
304             String JavaDoc i18nMsg = localStrings.getString(
305                 "con_mgr.resource_not_shareable");
306             throw new ResourceAllocationException( i18nMsg );
307                 }
308                 alloc =
309                     new LocalTxConnectorAllocator(poolmgr, mcf, spec,
310                                                   subject, cxRequestInfo,
311                                                   info, desc);
312                 return poolmgr.getResource(spec, alloc, info);
313             case ConnectorConstants.XA_TRANSACTION_INT:
314                 if (rarName.equals(ConnectorRuntime.DEFAULT_JMS_ADAPTER)) {
315                     shareable = false;
316                 }
317         spec.markAsXA();
318                 alloc =
319                     new ConnectorAllocator(poolmgr, mcf, spec,
320                                            subject, cxRequestInfo, info, desc,
321                                            shareable);
322                 return poolmgr.getResource(spec, alloc, info);
323             default:
324                 StringManager localStrings =
325                     StringManager.getManager(ConnectionManagerImpl.class);
326             String JavaDoc i18nMsg = localStrings.getString(
327             "con_mgr.illegal_tx_level", txLevel+ " ");
328                 throw new IllegalStateException JavaDoc(i18nMsg);
329             }
330
331         } catch (PoolingException ex) {
332             _logger.log(Level.WARNING,"poolmgr.get_connection_failure",ex.getMessage());
333             StringManager localStrings =
334                 StringManager.getManager(ConnectionManagerImpl.class);
335             String JavaDoc i18nMsg = localStrings.getString(
336             "con_mgr.error_creating_connection", ex.getMessage() );
337             ResourceAllocationException rae = new ResourceAllocationException(
338             i18nMsg );
339         rae.initCause( ex );
340             throw rae;
341         }
342     }
343
344       
345     public void setRarName( String JavaDoc _rarName ) {
346         rarName = _rarName;
347     }
348
349     public String JavaDoc getRarName() {
350         return rarName;
351     }
352
353     /*
354     * This method is called from the ConnectorObjectFactory lookup
355     * With this we move all the housekeeping work in allocateConnection
356     * up-front
357     *
358     */

359     public void initialize() throws ConnectorRuntimeException {
360     
361         Switch sw = Switch.getSwitch();
362     if (sw.getContainerType() == ConnectorConstants.NON_ACC_CLIENT) {
363             //Invocation from a non-ACC client
364
try {
365             // Initialize Transaction service. By now the ORB must have
366
// been created during the new InitialContext() call using
367
// the ORBManager
368
PEORBConfigurator.initTransactionService(null, new Properties JavaDoc() );
369
370             if (sw.getTransactionManager() == null) {
371             sw.setTransactionManager(new J2EETransactionManagerOpt());
372         }
373                 // There wont be any invocation manager. So, treat this as a system
374
// resource.
375
jndiName = ResourceInstaller.getPMJndiName(jndiName);
376         } catch(Exception JavaDoc e) {
377             throw (ConnectorRuntimeException)
378                     new ConnectorRuntimeException(e.getMessage()).initCause(e);
379         }
380     }
381         
382         ConnectorRuntime runtime = ConnectorRuntime.getRuntime();
383         ManagedConnectionFactory mcf = runtime.obtainManagedConnectionFactory(poolName);
384     ConnectorRegistry registry = ConnectorRegistry.getInstance();
385         PoolMetaData pmd = registry.getPoolMetaData( poolName );
386         defaultPrin = pmd.getResourcePrincipal();
387
388     }
389     
390     private void validatePool() throws ResourceException JavaDoc{
391         ConnectorRegistry registry = ConnectorRegistry.getInstance();
392         if (registry.getPoolMetaData(poolName) == null){
393             StringManager localStrings =
394                 StringManager.getManager(ConnectionManagerImpl.class);
395             String JavaDoc msg = localStrings.getString("con_mgr.no_pool_meta_data");
396             throw new ResourceException JavaDoc(poolName + ": " + msg);
397             }
398     }
399 }
400
Popular Tags