All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.appserv.connectors.internal.api.AppSpecificConnectorClassLoaderUtil Maven / Gradle / Ivy

There is a newer version: 7.2024.1.Alpha1
Show newest version
/*
 * 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 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();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy