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

com.ebay.jetstream.config.Configuration Maven / Gradle / Ivy

/*******************************************************************************
 *  Copyright © 2012-2015 eBay Software Foundation
 *  This program is dual licensed under the MIT and Apache 2.0 licenses.
 *  Please see LICENSE for more information.
 *******************************************************************************/
/**
 *
 */
package com.ebay.jetstream.config;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.AbstractBeanDefinitionReader;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;

import com.ebay.jetstream.config.mongo.MongoDbResource;
import com.ebay.jetstream.spring.beans.factory.support.UpdateableListableBeanFactory;
import com.ebay.jetstream.spring.context.support.AbstractUpdateableApplicationContext;
import com.ebay.jetstream.util.CommonUtils;

/**
 * 
 */
public class Configuration extends AbstractUpdateableApplicationContext {
  protected static final Logger LOGGER = LoggerFactory.getLogger(Configuration.class.getName());

  /**
   * @param clazz
   *            the class whose package should be searched
   * @param name
   *            the name of the context container, or null. If null, the class name itself is used as container name.
   * @return the Spring form of the context container in the given class location.
   */
  public static String getClasspathContext(Class clazz, String name) {
    String path = "classpath:" + clazz.getCanonicalName().replace('.', '/');
    return name == null ? path + ".xml" : path.substring(0, path.lastIndexOf('/') + 1) + name;
  }

  /**
   * Looks for classpath contexts matching the class name or any super class or interface.
   * 
   * @param clazz
   *            the class leaf to look for contexts
   * @return all files matching the class name but ending in .xml for all impls and interfaces
   */
  public static List getClasspathContexts(Class clazz) {
    List names = new ArrayList();
    for (Class current = clazz; current != null; current = current.getSuperclass())
      checkClass(names, current);
    for (Class current : clazz.getInterfaces())
      checkClass(names, current);
    return names;
  }

  /**
   * Returns all context files at the given path, across multiple data stores: files, svn/dav, etc.
   * 
   * @param path
   *            the directory path to look for context files.
   * @return all files ending in .xml at the given path.
   */
  public static List getContexts(String path) {
    try {
      ConfigDataSource cds = ConfigUtils.getConfigDataSource(path);
      List names = new ArrayList(cds.getStreamLocations());
      for (int i = names.size() - 1; i >= 0; i--)
        if (!names.get(i).toUpperCase().endsWith(".XML"))
          names.remove(i);
      return names;
    }
    catch (Throwable t) {
      throw CommonUtils.runtimeException(t);
    }
  }
  
  public static List getMongoContexts() {
    List mongo = new ArrayList();
    
    String mongoInfo = ConfigUtils.getPropOrEnv("MONGO_HOME");
    //if (!CommonUtils.isEmptyTrimmed(mongoInfo))
    if(mongoInfo != null && !CommonUtils.isEmptyTrimmed(mongoInfo)) {
    	mongo.add(mongoInfo);
    } else {
    	mongo.add("mongo:null");
    }
    	
    
    return mongo;
  }

  /**
   * Returns the ldap urls to get configuration information from. Currently only one ldap url is returned, and only if
   * the LDAPINFORMATION property or env var is populated.
   * 
   * @return the list of ldap urls
   */
  public static List getLdapContexts(ApplicationInformation ai) {
    List ldap = new ArrayList();
    String ldapInfo = ConfigUtils.getPropOrEnv("LDAPINFORMATION");
    if (ldapInfo != null) {
      int indexOfAt = ldapInfo.indexOf('@');
      if (indexOfAt != -1 && ai.containsKey("ldapHostPort") && ldapInfo.charAt(indexOfAt + 1) == '/') {
        ldapInfo = ldapInfo.substring(0, indexOfAt + 1) + ai.get("ldapHostPort") + ldapInfo.substring(indexOfAt + 1);
      }
      else if (indexOfAt != -1 && !ai.containsKey("ldapHostPort") && ldapInfo.charAt(indexOfAt + 1) == '/') {
        throw new RuntimeException("Ldap host/port not set");
      }
      if (!ldapInfo.contains("application=") && ai.containsKey("applicationName"))
        ldapInfo = addToUrlEnd(ldapInfo, "application=" + ai.get("applicationName"));
      if (!ldapInfo.contains("version=") && ai.containsKey("configVersion"))
        ldapInfo = addToUrlEnd(ldapInfo, "version=" + ai.get("configVersion"));
      if (!ldapInfo.contains("scope="))
        ldapInfo = addToUrlEnd(ldapInfo, "scope=" + ai.get("scope"));
    }
    if (!CommonUtils.isEmptyTrimmed(ldapInfo))
      ldap.add(ldapInfo);
    return ldap;
  }

  private static String addToUrlEnd(String begin, String string) {
    return begin + (begin.charAt(begin.length() - 1) == '/' ? string : "," + string);
  }

  private static ApplicationInformation checkAppInfo(ApplicationInformation ai) {
    if (ai == null)
      throw new NullPointerException("missing ApplicationInformation");
    return ai;
  }

  private static void checkClass(List names, Class clazz) {
    if (clazz.getResource(clazz.getSimpleName() + ".xml") != null)
      names.add(getClasspathContext(clazz, null));
  }

  private final ApplicationInformation m_applicationInformation;
  private final String[] m_configLocations;
  private Resource[] m_configResources;

  public Configuration(ApplicationInformation appInfo, String[] configLocations) {
    this(null, checkAppInfo(appInfo), configLocations);
  }

  public Configuration(String[] configLocations) {
    this(null, null, configLocations);
  }

  private Configuration(ApplicationContext parent, ApplicationInformation appInfo, String[] configLocations) {
    super(parent);
    LOGGER.info("Initializing " + getClass().getSimpleName() + " for application " + appInfo + ", context containers:");
    for (String cl : configLocations)
      LOGGER.info("  " + cl);
    m_applicationInformation = appInfo;
    m_configLocations = configLocations;
    getConfigResources(); // Initialize config resources
    refresh();
    // Ldap listens to configuration events as well as broadcast messages
    for (Resource resource : getConfigResources()) {
    	    	
    	if (resource instanceof MongoDbResource) {
    		((MongoDbResource) resource).listen(appInfo);
    	}
    }
      
  }

  public ApplicationInformation getApplicationInformation() {
    return m_applicationInformation;
  }

  public Resource[] getConfigResources() {
    if (m_configResources == null) {
      String[] configLocations = m_configLocations;
      List resources = new ArrayList();
      for (String configLocation : configLocations)
        try {
          for (Resource resource : getResources(configLocation))
            resources.add(resource);
        }
        catch (IOException e) {
          LOGGER.error("Failed to load " + configLocation + ": " + e);
        }
      m_configResources = resources.toArray(new Resource[] {});
    }
    return m_configResources;
  }

  @Override
  public void refresh() throws BeansException, IllegalStateException {
    try {
      super.refresh();
    }
    finally {
    }
  }

  @Override
  protected Resource getResourceByPath(String path) {
    if (m_configResources != null)
      for (Resource r : m_configResources)
        try {
          URL url = r.getURL();
          if (url != null && path.equals(url.toExternalForm()))
            return r;
        }
        catch (IOException e) { // NOPMD
          // Ignore
        }

    try {
      if (path.startsWith("http:") || path.startsWith("https:"))
        return new UrlResource(path);

      if (path.startsWith("mongo:") || path.startsWith("mongos:"))
          return new MongoDbResource(this, path);

      if (path.startsWith("classpath:"))
        return new ClassPathResource(path, Configuration.class);

      return new FileSystemResource(path);
    }
    catch (Throwable t) {
      LOGGER.error( "Failed to load " + path + ": " + t);
      throw CommonUtils.runtimeException(t);
    }
  }

  @Override
  protected void loadBeanDefinitions(UpdateableListableBeanFactory beanFactory) throws IOException, BeansException {
    AbstractBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    for (Resource resource : getConfigResources()) {
      if (resource instanceof MongoDbResource) {
	        ((MongoDbResource) resource).loadBeanDefinitions(beanFactory);
	  }
      else {
        beanDefinitionReader.loadBeanDefinitions(resource);
      }
    }
  }

  @Override
  protected void onRefresh() throws BeansException {
    super.onRefresh();
    ApplicationInformation ai = getApplicationInformation();
    if (ai != null)
      ai.onRefresh(this);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy