/*******************************************************************************
* 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.config;
import org.cloudfoundry.identity.uaa.impl.config.SystemEnvironmentAccessor;
import org.cloudfoundry.identity.uaa.impl.config.YamlServletProfileInitializer;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.util.Log4jConfigurer;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.support.StandardServletEnvironment;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import java.util.Enumeration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.atLeastOnce;
import static org.springframework.util.StringUtils.hasText;
/**
* @author Dave Syer
*
*/
public class YamlServletProfileInitializerTests {
private YamlServletProfileInitializer initializer = new YamlServletProfileInitializer();
private ConfigurableWebApplicationContext context = Mockito.mock(ConfigurableWebApplicationContext.class);
private StandardServletEnvironment environment = new StandardServletEnvironment();
private ServletConfig servletConfig = Mockito.mock(ServletConfig.class);
private ServletContext servletContext = Mockito.mock(ServletContext.class);
private static String activeProfiles;
@BeforeClass
public static void saveProfiles() {
activeProfiles = System.getProperty("spring.profiles.active");
}
@AfterClass
public static void restoreProfiles() {
if (activeProfiles != null) {
System.setProperty("spring.profiles.active", activeProfiles);
} else {
System.clearProperty("spring.profiles.active");
}
}
@Before
public void setup() {
Mockito.when(servletConfig.getInitParameterNames()).thenReturn(new EmptyEnumerationOfString());
Mockito.when(servletContext.getInitParameterNames()).thenReturn(new EmptyEnumerationOfString());
Mockito.when(context.getServletConfig()).thenReturn(servletConfig);
Mockito.when(context.getServletContext()).thenReturn(servletContext);
Mockito.when(context.getEnvironment()).thenReturn(environment);
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
System.err.println(invocation.getArguments()[0]);
return null;
}
}).when(servletContext).log(Matchers.anyString());
Mockito.when(servletContext.getContextPath()).thenReturn("/context");
}
@After
public void cleanup() throws Exception {
System.clearProperty("APPLICATION_CONFIG_URL");
System.clearProperty("LOG_FILE");
System.clearProperty("LOG_PATH");
Log4jConfigurer.initLogging("classpath:log4j.properties");
}
@Test
public void testLoadDefaultResource() throws Exception {
Mockito.when(context.getResource(Matchers.contains("${APPLICATION_CONFIG_URL}"))).thenReturn(
new ByteArrayResource("foo: bar\nspam:\n foo: baz".getBytes()));
initializer.initialize(context);
assertEquals("bar", environment.getProperty("foo"));
assertEquals("baz", environment.getProperty("spam.foo"));
}
@Test
public void testActiveProfiles() throws Exception {
System.setProperty("spring.profiles.active", "foo");
Mockito.when(context.getResource(Matchers.anyString())).thenReturn(
new ByteArrayResource("spring_profiles: bar".getBytes()));
initializer.initialize(context);
assertEquals("bar", environment.getActiveProfiles()[0]);
}
@Test
public void testActiveProfilesFromYaml() throws Exception {
Mockito.when(context.getResource(Matchers.anyString())).thenReturn(
new ByteArrayResource("spring_profiles: bar".getBytes()));
initializer.initialize(context);
assertEquals("bar", environment.getActiveProfiles()[0]);
}
@Test
public void testLog4jFileFromYaml() throws Exception {
Mockito.when(context.getResource(Matchers.anyString())).thenReturn(
new ByteArrayResource("logging:\n file: /tmp/bar.log".getBytes()));
initializer.initialize(context);
assertEquals("/tmp/bar.log", System.getProperty("LOG_FILE"));
}
@Test
public void testLog4jPathFromYaml() throws Exception {
Mockito.when(context.getResource(Matchers.anyString())).thenReturn(
new ByteArrayResource("logging:\n path: /tmp/log/bar".getBytes()));
initializer.initialize(context);
assertEquals("/tmp/log/bar", System.getProperty("LOG_PATH"));
}
@Test
public void testLog4jConfigurationFromYaml() throws Exception {
Mockito.when(context.getResource(Matchers.anyString())).thenReturn(
new ByteArrayResource("logging:\n config: bar".getBytes()));
initializer.initialize(context);
}
@Test
public void testLoadServletConfiguredFilename() throws Exception {
Mockito.when(servletConfig.getInitParameter("APPLICATION_CONFIG_FILE")).thenReturn("/config/path/foo.yml");
Mockito.when(context.getResource(Matchers.eq("file:/config/path/foo.yml"))).thenReturn(
new ByteArrayResource("foo: bar\nspam:\n foo: baz".getBytes()));
initializer.initialize(context);
assertEquals("bar", environment.getProperty("foo"));
assertEquals("baz", environment.getProperty("spam.foo"));
}
@Test
public void testLoadServletConfiguredResource() throws Exception {
Mockito.when(servletConfig.getInitParameter("environmentConfigLocations")).thenReturn("foo.yml");
Mockito.when(context.getResource(Matchers.eq("foo.yml"))).thenReturn(
new ByteArrayResource("foo: bar\nspam:\n foo: baz".getBytes()));
initializer.initialize(context);
assertEquals("bar", environment.getProperty("foo"));
assertEquals("baz", environment.getProperty("spam.foo"));
}
@Test
public void testLoadContextConfiguredResource() throws Exception {
Mockito.when(servletContext.getInitParameter("environmentConfigLocations")).thenReturn("foo.yml");
Mockito.when(context.getResource(Matchers.eq("foo.yml"))).thenReturn(
new ByteArrayResource("foo: bar\nspam:\n foo: baz".getBytes()));
initializer.initialize(context);
assertEquals("bar", environment.getProperty("foo"));
assertEquals("baz", environment.getProperty("spam.foo"));
}
@Test
public void testLoadReplacedResource() throws Exception {
System.setProperty("APPLICATION_CONFIG_URL", "file:foo/uaa.yml");
Mockito.when(context.getResource(Matchers.eq("file:foo/uaa.yml"))).thenReturn(
new ByteArrayResource("foo: bar\nspam:\n foo: baz".getBytes()));
initializer.initialize(context);
assertEquals("bar", environment.getProperty("foo"));
assertEquals("baz", environment.getProperty("spam.foo"));
}
@Test
public void testLoadReplacedResourceFromFileLocation() throws Exception {
System.setProperty("APPLICATION_CONFIG_FILE", "foo/uaa.yml");
Mockito.when(context.getResource(Matchers.eq("file:foo/uaa.yml"))).thenReturn(
new ByteArrayResource("foo: bar\nspam:\n foo: baz".getBytes()));
initializer.initialize(context);
assertEquals("bar", environment.getProperty("foo"));
assertEquals("baz", environment.getProperty("spam.foo"));
}
@Test
public void testLoggingConfigVariableWorks() throws Exception {
System.setProperty("APPLICATION_CONFIG_FILE", "foo/uaa.yml");
Mockito.when(context.getResource(Matchers.eq("file:foo/uaa.yml"))).thenReturn(
new ByteArrayResource("logging:\n config: /some/path".getBytes()));
initializer.initialize(context);
assertEquals("/some/path", environment.getProperty("logging.config"));
assertNull(environment.getProperty("smtp.host"));
assertNull(environment.getProperty("smtp.port"));
}
@Test
public void testReadingYamlFromEnvironment() throws Exception {
testReadingYamlFromEnvironment(null);
}
@Test
public void testReadingYamlFromEnvironment_Rename_Env_Variable() throws Exception {
testReadingYamlFromEnvironment("Renaming environment variable");
}
public void testReadingYamlFromEnvironment(String variableName) throws Exception {
if (hasText(variableName)) {
initializer.setYamlEnvironmentVariableName(variableName);
}
SystemEnvironmentAccessor env = new SystemEnvironmentAccessor() {
@Override
public String getEnvironmentVariable(String name) {
return name.equals(initializer.getYamlEnvironmentVariableName()) ?
"uaa.url: http://uaa.test.url/\n" +
"login.url: http://login.test.url/\n" +
"smtp:\n" +
" host: mail.server.host\n" +
" port: 3535\n" :
null;
}
};
initializer.setEnvironmentAccessor(env);
initializer.initialize(context);
assertEquals("mail.server.host", environment.getProperty("smtp.host"));
assertEquals("3535", environment.getProperty("smtp.port"));
assertEquals("http://uaa.test.url/", environment.getProperty("uaa.url"));
assertEquals("http://login.test.url/", environment.getProperty("login.url"));
}
@Test
public void testIgnoreDashDTomcatLoggingConfigVariable() throws Exception {
final String tomcatLogConfig = "-Djava.util.logging.config=/some/path/logging.properties";;
System.setProperty("APPLICATION_CONFIG_FILE", "foo/uaa.yml");
ArgumentCaptor<String> servletLogCaptor = ArgumentCaptor.forClass(String.class);
Mockito.when(context.getResource(Matchers.eq("file:foo/uaa.yml"))).thenReturn(
new ByteArrayResource(("logging:\n config: "+tomcatLogConfig).getBytes()));
environment.getPropertySources().addFirst(new PropertySource<Object>(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME) {
@Override
public boolean containsProperty(String name) {
if ("LOGGING_CONFIG".equals(name)) {
return true;
} else {
return super.containsProperty(name);
}
}
@Override
public Object getProperty(String name) {
if ("LOGGING_CONFIG".equals(name)) {
return tomcatLogConfig;
} else {
return System.getenv(name);
}
}
});
initializer.initialize(context);
assertEquals("-Djava.util.logging.config=/some/path/logging.properties", environment.getProperty("logging.config"));
Mockito.verify(servletContext,atLeastOnce()).log(servletLogCaptor.capture());
boolean logEntryFound = false;
for (String s : servletLogCaptor.getAllValues()) {
if (s.startsWith("Ignoring Log Config Location") && s.contains("Tomcat startup script environment variable")) {
logEntryFound = true;
}
}
assertTrue("Expected to find a log entry indicating that the LOGGING_CONFIG variable was found.", logEntryFound);
}
private static class EmptyEnumerationOfString implements Enumeration<String> {
@Override
public boolean hasMoreElements() {
return false;
}
@Override
public String nextElement() {
return null;
}
}
}