com.sun.appserv.connectors.internal.api.AppSpecificConnectorClassLoaderUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2009-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2016-2021] [Payara Foundation and/or its affiliates]
package com.sun.appserv.connectors.internal.api;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.inject.Provider;
import com.sun.enterprise.config.serverbeans.Applications;
import com.sun.enterprise.config.serverbeans.BindableResource;
import com.sun.enterprise.config.serverbeans.Domain;
import com.sun.enterprise.config.serverbeans.Module;
import com.sun.enterprise.config.serverbeans.Resource;
import com.sun.enterprise.config.serverbeans.ResourcePool;
import com.sun.enterprise.config.serverbeans.Resources;
import com.sun.enterprise.deployment.Application;
import com.sun.enterprise.deployment.BundleDescriptor;
import com.sun.enterprise.deployment.ConnectorDescriptor;
import com.sun.enterprise.deployment.EjbBundleDescriptor;
import com.sun.enterprise.deployment.EjbDescriptor;
import com.sun.enterprise.deployment.EjbInterceptor;
import com.sun.enterprise.deployment.EjbMessageBeanDescriptor;
import com.sun.enterprise.deployment.JndiNameEnvironment;
import com.sun.enterprise.deployment.ManagedBeanDescriptor;
import com.sun.enterprise.deployment.ResourceEnvReferenceDescriptor;
import com.sun.enterprise.deployment.ResourceReferenceDescriptor;
import com.sun.enterprise.deployment.runtime.connector.ResourceAdapter;
import com.sun.enterprise.deployment.runtime.connector.SunConnector;
import com.sun.enterprise.deployment.util.DOLUtils;
import com.sun.logging.LogDomains;
import org.glassfish.api.admin.ServerEnvironment;
import org.glassfish.connectors.config.AdminObjectResource;
import org.glassfish.connectors.config.ConnectorConnectionPool;
import org.glassfish.connectors.config.ConnectorResource;
import org.glassfish.connectors.config.ConnectorService;
import org.glassfish.connectors.config.ResourceAdapterConfig;
import org.glassfish.connectors.config.WorkSecurityMap;
import org.glassfish.deployment.common.Descriptor;
import org.glassfish.deployment.common.ModuleDescriptor;
import org.glassfish.deployment.common.RootDeploymentDescriptor;
import org.glassfish.internal.data.ApplicationInfo;
import org.glassfish.internal.data.ApplicationRegistry;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.config.types.Property;
@Service
public class AppSpecificConnectorClassLoaderUtil {
@Inject
private ApplicationRegistry appRegistry;
@Inject
@Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
private Provider connectorServiceProvider;
@Inject
private Provider connectorsClassLoaderUtilProvider;
@Inject
private Provider domainProvider;
@Inject
private Provider applicationsProvider;
private static final Logger _logger =
LogDomains.getLogger(AppSpecificConnectorClassLoaderUtil.class, LogDomains.RSR_LOGGER);
/**
* {@inheritDoc}
*/
public void detectReferredRARs(String appName) {
ApplicationInfo appInfo = appRegistry.get(appName);
//call to detectReferredRAs can be called only when appInfo is available
if (appInfo == null) {
throw new IllegalStateException("ApplicationInfo is not available for application [ " + appName + " ]");
}
Application app = appInfo.getMetaData(Application.class);
if(!appInfo.isJavaEEApp()){
if(_logger.isLoggable(Level.FINEST)){
_logger.finest("Application ["+appName+"] is not a Java EE application, skipping " +
"resource-adapter references detection");
}
return;
}
// Iterate through all bundle descriptors, ejb-descriptors, managed-bean descriptors
// for references to resource-adapters
//
// References can be via :
// resource-ref
// resource-env-ref
// ra-mid
//
// Resource definition can be found in :
// domain.xml
// sun-ra.xml
// default connector resource
//handle application.xml bundle descriptor
processDescriptorForRAReferences(app, null, app);
Collection bundleDescriptors = app.getBundleDescriptors();
//TODO Similar reference checking mechanism is used in DataSourceDefinitionDeployer. Merge them ?
//bundle descriptors
for (BundleDescriptor bundleDesc : bundleDescriptors) {
String moduleName = getModuleName(bundleDesc, app);
processDescriptorForRAReferences(app, bundleDesc, moduleName);
Collection dds = bundleDesc.getExtensionsDescriptors();
if(dds != null){
for(RootDeploymentDescriptor dd : dds){
processDescriptorForRAReferences(app, dd, moduleName);
}
}
}
}
private void processDescriptorForRAReferences(Application app, Descriptor descriptor, String moduleName) {
if (descriptor instanceof JndiNameEnvironment) {
processDescriptorForRAReferences(app, moduleName, (JndiNameEnvironment) descriptor);
}
// ejb descriptors
if (descriptor instanceof EjbBundleDescriptor) {
EjbBundleDescriptor ejbDesc = (EjbBundleDescriptor) descriptor;
Set extends EjbDescriptor> ejbDescriptors = ejbDesc.getEjbs();
for (EjbDescriptor ejbDescriptor : ejbDescriptors) {
processDescriptorForRAReferences(app, moduleName, ejbDescriptor);
if (ejbDescriptor instanceof EjbMessageBeanDescriptor) {
EjbMessageBeanDescriptor messageBeanDesc = (EjbMessageBeanDescriptor) ejbDescriptor;
String raMid = messageBeanDesc.getResourceAdapterMid();
//there seem to be applications that do not specify ra-mid
if (raMid != null) {
app.addResourceAdapter(raMid);
}
}
}
//ejb interceptors
Set ejbInterceptors = ejbDesc.getInterceptors();
for (EjbInterceptor ejbInterceptor : ejbInterceptors) {
processDescriptorForRAReferences(app, moduleName, ejbInterceptor);
}
}
if(descriptor instanceof BundleDescriptor){
// managed bean descriptors
Set managedBeanDescriptors = ((BundleDescriptor)descriptor).getManagedBeans();
for (ManagedBeanDescriptor mbd : managedBeanDescriptors) {
processDescriptorForRAReferences(app, moduleName, mbd);
}
}
}
private String getModuleName(BundleDescriptor bundleDesc, Application app) {
Set> moduleDescriptors = app.getModules();
if(moduleDescriptors != null){
for(ModuleDescriptor moduleDesc : moduleDescriptors){
if(bundleDesc.equals(moduleDesc.getDescriptor())){
return moduleDesc.getModuleName();
}
}
}
return null;
}
/**
* {@inheritDoc}
*/
public Set getRARsReferredByApplication(String appName) {
ApplicationInfo appInfo = appRegistry.get(appName);
if (appInfo != null) {
Application app = appInfo.getMetaData(Application.class);
if(appInfo.isJavaEEApp()){
return app.getResourceAdapters();
}
}
return new HashSet();
}
private void processDescriptorForRAReferences(com.sun.enterprise.deployment.Application app,
String moduleName, JndiNameEnvironment jndiEnv) {
// resource-ref
for (Object resourceRef : jndiEnv.getResourceReferenceDescriptors()) {
ResourceReferenceDescriptor resRefDesc = (ResourceReferenceDescriptor) resourceRef;
String jndiName = resRefDesc.getJndiName();
//ignore refs where jndi-name is not available
if(jndiName != null){
detectResourceInRA(app, moduleName, jndiName);
}
}
// resource-env-ref
for (Object resourceEnvRef : jndiEnv.getResourceEnvReferenceDescriptors()) {
ResourceEnvReferenceDescriptor resourceEnvRefDesc = (ResourceEnvReferenceDescriptor) resourceEnvRef;
String jndiName = resourceEnvRefDesc.getJndiName();
//ignore refs where jndi-name is not available
if(jndiName != null){
detectResourceInRA(app, moduleName, jndiName);
}
}
}
private void detectResourceInRA(Application app, String moduleName, String jndiName) {
//domain.xml
Resource res = null;
if(jndiName.startsWith(ConnectorConstants.JAVA_APP_SCOPE_PREFIX) /*|| jndiName.startsWith("java:global/")*/ ){
ApplicationInfo appInfo = appRegistry.get(app.getName());
res = getApplicationScopedResource(jndiName, BindableResource.class, appInfo);
}else if(jndiName.startsWith(ConnectorConstants.JAVA_MODULE_SCOPE_PREFIX)){
ApplicationInfo appInfo = appRegistry.get(app.getName());
res = getModuleScopedResource(jndiName, moduleName, BindableResource.class, appInfo);
}else{
res = ConnectorsUtil.getResourceByName(getResources(), BindableResource.class, jndiName);
}
//embedded ra's resources may not be created yet as they can be created only after .ear deploy
// (and .ear may refer to these resources in DD)
if (res != null) {
if (ConnectorResource.class.isAssignableFrom(res.getClass())) {
ConnectorResource connResource = (ConnectorResource)res;
String poolName = connResource.getPoolName();
Resource pool ;
ApplicationInfo appInfo = appRegistry.get(app.getName());
if(jndiName.startsWith(ConnectorConstants.JAVA_APP_SCOPE_PREFIX) /*|| jndiName.startsWith("java:global/")*/){
pool = getApplicationScopedResource(poolName, ResourcePool.class, appInfo);
} else if(jndiName.startsWith(ConnectorConstants.JAVA_MODULE_SCOPE_PREFIX)){
pool = getModuleScopedResource(poolName, moduleName, ResourcePool.class, appInfo);
} else{
pool = ConnectorsUtil.getResourceByName(getResources(), ResourcePool.class, poolName);
}
if (ConnectorConnectionPool.class.isAssignableFrom(pool.getClass())) {
String raName = ((ConnectorConnectionPool) pool).getResourceAdapterName();
app.addResourceAdapter(raName);
}
} else if (AdminObjectResource.class.isAssignableFrom(res.getClass())) {
String raName = ((AdminObjectResource) res).getResAdapter();
app.addResourceAdapter(raName);
}
} else {
boolean found = false;
//detect sun-ra.xml
// find all the standalone connector modules
List applications =
getApplications().getApplicationsWithSnifferType(com.sun.enterprise.config.serverbeans.ServerTags.CONNECTOR, true);
Iterator itr = applications.iterator();
while (itr.hasNext()) {
com.sun.enterprise.config.serverbeans.Application application =
(com.sun.enterprise.config.serverbeans.Application) itr.next();
String appName = application.getName();
ApplicationInfo appInfo = appRegistry.get(appName);
if (appInfo == null) {
continue; // the app is not deployed on this node
}
Application dolApp = appInfo.getMetaData(Application.class);
Collection rarDescriptors = dolApp.getBundleDescriptors(ConnectorDescriptor.class);
for (ConnectorDescriptor desc : rarDescriptors) {
SunConnector sunraDesc = desc.getSunDescriptor();
if (sunraDesc != null) {
String sunRAJndiName = (String) sunraDesc.getResourceAdapter().
getValue(ResourceAdapter.JNDI_NAME);
if (jndiName.equals(sunRAJndiName)) {
app.addResourceAdapter(desc.getName());
found = true;
break;
}
} else {
//check whether it is default resource in the connector
if (desc.getDefaultResourcesNames().contains(jndiName)) {
app.addResourceAdapter(desc.getName());
found = true;
break;
}
}
}
}
if (!found) {
if(DOLUtils.getDefaultLogger().isLoggable(Level.FINEST)) {
DOLUtils.getDefaultLogger().log(Level.FINEST, "could not find resource by name : " + jndiName);
}
}
}
}
private Resource getApplicationScopedResource(String name, Class type, ApplicationInfo appInfo){
Resource foundRes = null;
if(appInfo != null){
com.sun.enterprise.config.serverbeans.Application app =
appInfo.getTransientAppMetaData(com.sun.enterprise.config.serverbeans.ServerTags.APPLICATION,
com.sun.enterprise.config.serverbeans.Application.class);
Resources resources = null;
if(app != null){
resources = appInfo.getTransientAppMetaData(app.getName()+"-resources", Resources.class);
}
if(resources != null){
boolean bindableResource = BindableResource.class.isAssignableFrom(type);
boolean poolResource = ResourcePool.class.isAssignableFrom(type);
boolean workSecurityMap = WorkSecurityMap.class.isAssignableFrom(type);
boolean rac = ResourceAdapterConfig.class.isAssignableFrom(type);
Iterator itr = resources.getResources().iterator();
while(itr.hasNext()){
String resourceName = null;
Resource res = (Resource)itr.next();
if(bindableResource && res instanceof BindableResource){
resourceName = ((BindableResource)res).getJndiName();
} else if(poolResource && res instanceof ResourcePool){
resourceName = ((ResourcePool)res).getName();
} else if(rac && res instanceof ResourceAdapterConfig){
resourceName = ((ResourceAdapterConfig)res).getName();
} else if(workSecurityMap && res instanceof WorkSecurityMap){
resourceName = ((WorkSecurityMap)res).getName();
}
if(resourceName != null){
if(!(resourceName.startsWith(ConnectorConstants.JAVA_APP_SCOPE_PREFIX) /*||
resourceName.startsWith(ConnectorConstants.JAVA_GLOBAL_SCOPE_PREFIX)*/)){
resourceName = ConnectorConstants.JAVA_APP_SCOPE_PREFIX + resourceName;
}
if(!(name.startsWith(ConnectorConstants.JAVA_APP_SCOPE_PREFIX) /*||
name.startsWith(ConnectorConstants.JAVA_GLOBAL_SCOPE_PREFIX)*/)){
name = ConnectorConstants.JAVA_APP_SCOPE_PREFIX + name;
}
if(name.equals(resourceName)){
foundRes = res;
break;
}
}
}
}
}
return foundRes;
}
private Resource getModuleScopedResource(String name, String moduleName, Class type, ApplicationInfo appInfo){
Resource foundRes = null;
if(appInfo != null){
com.sun.enterprise.config.serverbeans.Application app =
appInfo.getTransientAppMetaData(com.sun.enterprise.config.serverbeans.ServerTags.APPLICATION,
com.sun.enterprise.config.serverbeans.Application.class);
Resources resources = null;
if(app != null){
Module module = null;
List modules = app.getModule();
for(Module m : modules){
if(ConnectorsUtil.getActualModuleName(m.getName()).equals(moduleName)){
module = m;
break;
}
}
if(module != null){
resources = appInfo.getTransientAppMetaData(module.getName()+"-resources", Resources.class);
}
}
if(resources != null){
boolean bindableResource = BindableResource.class.isAssignableFrom(type);
boolean poolResource = ResourcePool.class.isAssignableFrom(type);
boolean workSecurityMap = WorkSecurityMap.class.isAssignableFrom(type);
boolean rac = ResourceAdapterConfig.class.isAssignableFrom(type);
Iterator itr = resources.getResources().iterator();
while(itr.hasNext()){
String resourceName = null;
Resource res = (Resource)itr.next();
if(bindableResource && res instanceof BindableResource){
resourceName = ((BindableResource)res).getJndiName();
} else if(poolResource && res instanceof ResourcePool){
resourceName = ((ResourcePool)res).getName();
} else if(rac && res instanceof ResourceAdapterConfig){
resourceName = ((ResourceAdapterConfig)res).getName();
} else if(workSecurityMap && res instanceof WorkSecurityMap){
resourceName = ((WorkSecurityMap)res).getName();
}
if(resourceName != null){
if(!(resourceName.startsWith(ConnectorConstants.JAVA_MODULE_SCOPE_PREFIX) /*|| resourceName.startsWith("java:global/")*/)){
resourceName = ConnectorConstants.JAVA_MODULE_SCOPE_PREFIX + resourceName;
}
if(!(name.startsWith(ConnectorConstants.JAVA_MODULE_SCOPE_PREFIX) /*|| name.startsWith("java:global/")*/)){
name = ConnectorConstants.JAVA_MODULE_SCOPE_PREFIX + name;
}
if(name.equals(resourceName)){
foundRes = res;
break;
}
}
}
}
}
return foundRes;
}
public Collection getSystemRARClassLoaders() {
try {
return getConnectorsClassLoaderUtil().getSystemRARClassLoaders();
} catch (ConnectorRuntimeException cre) {
throw new RuntimeException(cre.getMessage(), cre);
}
}
public boolean useGlobalConnectorClassLoader() {
boolean flag = false;
ConnectorService connectorService = connectorServiceProvider.get();
//it is possible that connector-service is not yet defined in domain.xml
if(connectorService != null){
String classLoadingPolicy = connectorService.getClassLoadingPolicy();
if (classLoadingPolicy != null &&
classLoadingPolicy.equals(ConnectorConstants.CLASSLOADING_POLICY_GLOBAL_ACCESS)) {
flag = true;
}
}
return flag;
}
public Collection getRequiredResourceAdapters(String appName) {
List requiredRars = new ArrayList();
if (appName != null) {
ConnectorService connectorService = connectorServiceProvider.get();
//it is possible that connector-service is not yet defined in domain.xml
if (connectorService != null) {
if (appName.trim().length() > 0) {
Property property = connectorService.getProperty(appName.trim());
if (property != null) {
String requiredRarsString = property.getValue();
StringTokenizer tokenizer = new StringTokenizer(requiredRarsString, ",");
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken().trim();
requiredRars.add(token);
}
}
}
}
}
return requiredRars;
}
private ConnectorsClassLoaderUtil getConnectorsClassLoaderUtil() {
return connectorsClassLoaderUtilProvider.get();
}
private Resources getResources() {
return domainProvider.get().getResources();
}
private Applications getApplications() {
return applicationsProvider.get();
}
}