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

psiprobe.beans.ContainerWrapperBean Maven / Gradle / Ivy

There is a newer version: 5.1.1
Show newest version
/**
 * Licensed under the GPL License. You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 *
 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */
package psiprobe.beans;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.apache.catalina.Context;
import org.apache.catalina.Wrapper;
import org.apache.catalina.util.ServerInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import psiprobe.TomcatContainer;
import psiprobe.model.ApplicationResource;

/**
 * This class wires support for Tomcat "privileged" context functionality into Spring. If
 * application context is privileged Tomcat would always call servlet.setWrapper method on each
 * request. ContainerWrapperBean wires the passed wrapper to the relevant Tomcat container adapter
 * class, which in turn helps the Probe to interpret the wrapper.
 */
public class ContainerWrapperBean {

  /** The Constant logger. */
  private static final Logger logger = LoggerFactory.getLogger(ContainerWrapperBean.class);

  /** The tomcat container. */
  private volatile TomcatContainer tomcatContainer;

  /** The lock. */
  private final Object lock = new Object();

  /** List of class names to adapt particular Tomcat implementation to TomcatContainer interface. */
  @Inject
  private List adapterClasses;

  /** The resource resolver. */
  private ResourceResolver resourceResolver;

  /** The force first adapter. */
  private boolean forceFirstAdapter;

  /** The resource resolvers. */
  @Inject
  private Map resourceResolvers;

  /**
   * Checks if is force first adapter.
   *
   * @return true, if is force first adapter
   */
  public boolean isForceFirstAdapter() {
    return forceFirstAdapter;
  }

  /**
   * Sets the force first adapter. Setting this property to true will override the server polling
   * each adapter performs to test for compatibility. Instead, it will use the first one in the
   * adapterClasses list.
   *
   * @param forceFirstAdapter the new force first adapter
   */
  // TODO We should make this configurable
  @Value("false")
  public void setForceFirstAdapter(boolean forceFirstAdapter) {
    this.forceFirstAdapter = forceFirstAdapter;
  }

  /**
   * Sets the wrapper.
   *
   * @param wrapper the new wrapper
   */
  public void setWrapper(Wrapper wrapper) {
    if (tomcatContainer == null) {

      synchronized (lock) {

        if (tomcatContainer == null) {

          String serverInfo = ServerInfo.getServerInfo();
          logger.info("Server info: {}", serverInfo);
          for (String className : adapterClasses) {
            try {
              Object obj = Class.forName(className).getDeclaredConstructor().newInstance();
              logger.debug("Testing container adapter: {}", className);
              if (obj instanceof TomcatContainer) {
                if (forceFirstAdapter || ((TomcatContainer) obj).canBoundTo(serverInfo)) {
                  logger.info("Using {}", className);
                  tomcatContainer = (TomcatContainer) obj;
                  tomcatContainer.setWrapper(wrapper);
                  break;
                }
                logger.debug("Cannot bind {} to {}", className, serverInfo);
              } else {
                logger.error("{} does not implement {}", className,
                    TomcatContainer.class.getName());
              }
            } catch (Exception e) {
              logger.debug("", e);
              logger.info("Failed to load {}", className);
            }
          }

          if (tomcatContainer == null) {
            logger.error("No suitable container adapter found!");
          }
        }
      }
    }

    try {
      if (tomcatContainer != null && wrapper == null) {
        logger.info("Unregistering container adapter");
        tomcatContainer.setWrapper(null);
      }
    } catch (Exception e) {
      logger.error("Could not unregister container adapter", e);
    }
  }

  /**
   * Gets the tomcat container.
   *
   * @return the tomcat container
   */
  public TomcatContainer getTomcatContainer() {
    return tomcatContainer;
  }

  /**
   * Gets the adapter classes.
   *
   * @return the adapter classes
   */
  public List getAdapterClasses() {
    return adapterClasses;
  }

  /**
   * Sets the adapter classes.
   *
   * @param adapterClasses the new adapter classes
   */
  public void setAdapterClasses(List adapterClasses) {
    this.adapterClasses = adapterClasses;
  }

  /**
   * Gets the resource resolver.
   *
   * @return the resource resolver
   */
  public ResourceResolver getResourceResolver() {
    if (resourceResolver == null) {
      if (System.getProperty("jboss.server.name") != null) {
        resourceResolver = resourceResolvers.get("jboss");
        logger.info("Using JBOSS resource resolver");
      } else {
        resourceResolver = resourceResolvers.get("default");
        logger.info("Using DEFAULT resource resolver");
      }
    }
    return resourceResolver;
  }

  /**
   * Gets the resource resolvers.
   *
   * @return the resource resolvers
   */
  public Map getResourceResolvers() {
    return resourceResolvers;
  }

  /**
   * Sets the resource resolvers.
   *
   * @param resourceResolvers the resource resolvers
   */
  public void setResourceResolvers(Map resourceResolvers) {
    this.resourceResolvers = resourceResolvers;
  }

  /**
   * Gets the data sources.
   *
   * @return the data sources
   * @throws Exception the exception
   */
  public List getDataSources() throws Exception {
    List resources = new ArrayList<>();
    resources.addAll(getPrivateDataSources());
    resources.addAll(getGlobalDataSources());
    return resources;
  }

  /**
   * Gets the private data sources.
   *
   * @return the private data sources
   * @throws Exception the exception
   */
  public List getPrivateDataSources() throws Exception {
    List resources = new ArrayList<>();
    if (tomcatContainer != null && getResourceResolver().supportsPrivateResources()) {
      for (Context app : getTomcatContainer().findContexts()) {
        List appResources =
            getResourceResolver().getApplicationResources(app, this);
        // add only those resources that have data source info
        filterDataSources(appResources, resources);
      }
    }
    return resources;
  }

  /**
   * Gets the global data sources.
   *
   * @return the global data sources
   * @throws Exception the exception
   */
  public List getGlobalDataSources() throws Exception {
    List resources = new ArrayList<>();
    if (getResourceResolver().supportsGlobalResources()) {
      List globalResources = getResourceResolver().getApplicationResources();
      // add only those resources that have data source info
      filterDataSources(globalResources, resources);
    }
    return resources;
  }

  /**
   * Filter data sources.
   *
   * @param resources the resources
   * @param dataSources the data sources
   */
  protected void filterDataSources(List resources,
      List dataSources) {

    for (ApplicationResource res : resources) {
      if (res.getDataSourceInfo() != null) {
        dataSources.add(res);
      }
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy