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

org.cloudfoundry.identity.uaa.impl.config.YamlServletProfileInitializer Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 *     Cloud Foundry
 *     Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved.
 *
 *     This product is licensed to you under the Apache License, Version 2.0 (the "License").
 *     You may not use this product except in compliance with the License.
 *
 *     This product includes a number of subcomponents with
 *     separate copyright notices and license terms. Your use of these
 *     subcomponents is subject to the terms and conditions of the
 *     subcomponent's license, as noted in the LICENSE file.
 *******************************************************************************/
package org.cloudfoundry.identity.uaa.impl.config;

import org.apache.log4j.MDC;
import org.cloudfoundry.identity.uaa.impl.config.YamlProcessor.ResolutionMethod;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.security.util.InMemoryResource;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.util.Log4jConfigurer;
import org.springframework.util.StringUtils;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.yaml.snakeyaml.Yaml;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
import static org.springframework.util.StringUtils.hasText;
import static org.springframework.util.StringUtils.isEmpty;

/**
 * An {@link ApplicationContextInitializer} for a web application to enable it
 * to externalize the environment and
 * logging configuration. A YAML config file is loaded if present and inserted
 * into the environment. In addition if the
 * YAML contains some special properties, some initialization is carried out:
 *
 * 
    *
  • spring_profiles - then the active profiles are set
  • *
  • logging.config - then log4j is initialized from that * location (if it exists)
  • *
* * * */ public class YamlServletProfileInitializer implements ApplicationContextInitializer { private static final String PROFILE_CONFIG_FILE_LOCATIONS = "environmentConfigLocations"; private static final String PROFILE_CONFIG_FILE_DEFAULT = "environmentConfigDefaults"; public static final String[] DEFAULT_PROFILE_CONFIG_FILE_LOCATIONS = new String[] { "${APPLICATION_CONFIG_URL}", "file:${APPLICATION_CONFIG_FILE}" }; private static final String DEFAULT_YAML_KEY = "environmentYamlKey"; private String rawYamlKey = DEFAULT_YAML_KEY; private String yamlEnvironmentVariableName = "UAA_CONFIG_YAML"; private SystemEnvironmentAccessor environmentAccessor = new SystemEnvironmentAccessor(){}; @Override public void initialize(ConfigurableWebApplicationContext applicationContext) { ServletContext servletContext = applicationContext.getServletContext(); HttpSessionEventPublisher publisher = new HttpSessionEventPublisher(); servletContext.addListener(publisher); WebApplicationContextUtils.initServletPropertySources(applicationContext.getEnvironment().getPropertySources(), servletContext, applicationContext.getServletConfig()); ServletConfig servletConfig = applicationContext.getServletConfig(); String locations = servletConfig == null ? null : servletConfig.getInitParameter(PROFILE_CONFIG_FILE_LOCATIONS); List resources = new ArrayList<>(); //add default locations first Set defaultLocation = StringUtils.commaDelimitedListToSet(servletConfig == null ? null : servletConfig.getInitParameter(PROFILE_CONFIG_FILE_DEFAULT)); if (defaultLocation != null && defaultLocation.size()>0) { for (String s : defaultLocation) { Resource defaultResource = new ClassPathResource(s); if (defaultResource.exists()) { resources.add(defaultResource); } } } resources.addAll(getResource(servletContext, applicationContext, locations)); Resource yamlFromEnv = getYamlFromEnvironmentVariable(); if (yamlFromEnv!=null) { resources.add(yamlFromEnv); } if (resources.isEmpty()) { servletContext.log("No YAML environment properties from servlet. Defaulting to servlet context."); locations = servletContext.getInitParameter(PROFILE_CONFIG_FILE_LOCATIONS); resources.addAll(getResource(servletContext, applicationContext, locations)); } try { servletContext.log("Loading YAML environment properties from location: " + resources.toString()); YamlMapFactoryBean factory = new YamlMapFactoryBean(); factory.setResolutionMethod(ResolutionMethod.OVERRIDE_AND_IGNORE); factory.setResources(resources.toArray(new Resource[resources.size()])); Map map = factory.getObject(); String yamlStr = (new Yaml()).dump(map); map.put(rawYamlKey, yamlStr); NestedMapPropertySource properties = new NestedMapPropertySource("servletConfigYaml", map); applicationContext.getEnvironment().getPropertySources().addLast(properties); applySpringProfiles(applicationContext.getEnvironment(), servletContext); applyLog4jConfiguration(applicationContext.getEnvironment(), servletContext); } catch (Exception e) { servletContext.log("Error loading YAML environment properties from location: " + resources.toString(), e); } } protected Resource getYamlFromEnvironmentVariable() { if (getEnvironmentAccessor()!=null){ String data = getEnvironmentAccessor().getEnvironmentVariable(getYamlEnvironmentVariableName()); if (hasText(data)) { //validate the Yaml? We don't do that for the others return new InMemoryResource(data); } } return null; } private List getResource(ServletContext servletContext, ConfigurableWebApplicationContext applicationContext, String locations) { List resources = new LinkedList<>(); String[] configFileLocations = locations == null ? DEFAULT_PROFILE_CONFIG_FILE_LOCATIONS : StringUtils .commaDelimitedListToStringArray(locations); for (String location : configFileLocations) { location = applicationContext.getEnvironment().resolvePlaceholders(location); servletContext.log("Testing for YAML resources at: " + location); Resource resource = applicationContext.getResource(location); if (resource != null && resource.exists()) { resources.add(resource); } } return resources; } private void applyLog4jConfiguration(ConfigurableEnvironment environment, ServletContext servletContext) { String log4jConfigLocation = "classpath:log4j.properties"; if (environment.containsProperty("logging.file")) { String location = environment.getProperty("logging.file"); servletContext.log("Setting LOG_FILE: " + location); System.setProperty("LOG_FILE", location); } else if (environment.containsProperty("logging.path")) { String location = environment.getProperty("logging.path"); servletContext.log("Setting LOG_PATH: " + location); System.setProperty("LOG_PATH", location); } else if (environment.containsProperty("logging.config")) { //tomcat sets the LOGGING_CONFIG environment variable, //we do not want that variable //this variable starts with -D, so we can ignore it. String location = environment.getProperty("logging.config"); if (location!=null && location.trim().length()>0) { PropertySource environmentPropertySource = environment.getPropertySources().get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME); if ((location.startsWith("-D") && environmentPropertySource!=null && location.equals(environmentPropertySource.getProperty("LOGGING_CONFIG")))) { servletContext.log("Ignoring Log Config Location: " + location + ". Location is suspect to be a Tomcat startup script environment variable"); } else { servletContext.log("Setting Log Config Location: " + location + " based on logging.config setting."); log4jConfigLocation = environment.getProperty("logging.config"); } } } try { servletContext.log("Loading log4j config from location: " + log4jConfigLocation); Log4jConfigurer.initLogging(log4jConfigLocation); } catch (FileNotFoundException e) { servletContext.log("Error loading log4j config from location: " + log4jConfigLocation, e); } MDC.put("context", servletContext.getContextPath()); } protected void applySpringProfiles(ConfigurableEnvironment environment, ServletContext servletContext) { String systemProfiles = System.getProperty("spring.profiles.active"); environment.setDefaultProfiles(new String[0]); if (environment.containsProperty("spring_profiles")) { String profiles = environment.getProperty("spring_profiles"); servletContext.log("Setting active profiles: " + profiles); environment.setActiveProfiles(StringUtils.tokenizeToStringArray(profiles, ",", true, true)); } else { if (isEmpty(systemProfiles)) { environment.setActiveProfiles("hsqldb"); } else { environment.setActiveProfiles(commaDelimitedListToStringArray(systemProfiles)); } } } public String getYamlEnvironmentVariableName() { return yamlEnvironmentVariableName; } public void setYamlEnvironmentVariableName(String yamlEnvironmentVariableName) { this.yamlEnvironmentVariableName = yamlEnvironmentVariableName; } public SystemEnvironmentAccessor getEnvironmentAccessor() { return environmentAccessor; } public void setEnvironmentAccessor(SystemEnvironmentAccessor environmentAccessor) { this.environmentAccessor = environmentAccessor; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy