下面列出了org.springframework.core.env.MutablePropertySources#addLast ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Test
@SuppressWarnings("serial")
public void explicitPropertySourcesExcludesLocalProperties() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerBeanDefinition("testBean",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${my.name}")
.getBeanDefinition());
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(new MockPropertySource());
PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
ppc.setPropertySources(propertySources);
ppc.setProperties(new Properties() {{
put("my.name", "local");
}});
ppc.setIgnoreUnresolvablePlaceholders(true);
ppc.postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), equalTo("${my.name}"));
}
@Test
public void explicitPropertySourcesExcludesEnvironment() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerBeanDefinition("testBean",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${my.name}")
.getBeanDefinition());
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(new MockPropertySource());
PropertySourcesPlaceholderConfigurer pc = new PropertySourcesPlaceholderConfigurer();
pc.setPropertySources(propertySources);
pc.setEnvironment(new MockEnvironment().withProperty("my.name", "env"));
pc.setIgnoreUnresolvablePlaceholders(true);
pc.postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), equalTo("${my.name}"));
assertEquals(pc.getAppliedPropertySources().iterator().next(), propertySources.iterator().next());
}
@Test
@SuppressWarnings("serial")
public void explicitPropertySourcesExcludesLocalProperties() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerBeanDefinition("testBean",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${my.name}")
.getBeanDefinition());
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(new MockPropertySource());
PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
ppc.setPropertySources(propertySources);
ppc.setProperties(new Properties() {{
put("my.name", "local");
}});
ppc.setIgnoreUnresolvablePlaceholders(true);
ppc.postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), equalTo("${my.name}"));
}
/**
* Don't use ConfigurableEnvironment.merge() in case there are clashes with
* property source names
*
* @param input
* @return
*/
private StandardEnvironment copyEnvironment(ConfigurableEnvironment input) {
StandardEnvironment environment = new StandardEnvironment();
MutablePropertySources capturedPropertySources = environment.getPropertySources();
// Only copy the default property source(s) and the profiles over from
// the main environment (everything else should be pristine, just like
// it was on startup).
for (String name : DEFAULT_PROPERTY_SOURCES) {
if (input.getPropertySources().contains(name)) {
if (capturedPropertySources.contains(name)) {
capturedPropertySources.replace(name, input.getPropertySources().get(name));
} else {
capturedPropertySources.addLast(input.getPropertySources().get(name));
}
}
}
environment.setActiveProfiles(input.getActiveProfiles());
environment.setDefaultProfiles(input.getDefaultProfiles());
Map<String, Object> map = new HashMap<String, Object>();
map.put("spring.jmx.enabled", false);
map.put("spring.main.sources", "");
capturedPropertySources.addFirst(new MapPropertySource(SCM_REFRESH_PROPERTY_SOURCE, map));
return environment;
}
private void addPropertySource(PropertySource<?> propertySource) {
String name = propertySource.getName();
MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment).getPropertySources();
if (this.propertySourceNames.contains(name)) {
// We've already added a version, we need to extend it
PropertySource<?> existing = propertySources.get(name);
if (existing != null) {
PropertySource<?> newSource = (propertySource instanceof ResourcePropertySource ?
((ResourcePropertySource) propertySource).withResourceName() : propertySource);
if (existing instanceof CompositePropertySource) {
((CompositePropertySource) existing).addFirstPropertySource(newSource);
}
else {
if (existing instanceof ResourcePropertySource) {
existing = ((ResourcePropertySource) existing).withResourceName();
}
CompositePropertySource composite = new CompositePropertySource(name);
composite.addPropertySource(newSource);
composite.addPropertySource(existing);
propertySources.replace(name, composite);
}
return;
}
}
if (this.propertySourceNames.isEmpty()) {
propertySources.addLast(propertySource);
}
else {
String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1);
propertySources.addBefore(firstProcessed, propertySource);
}
this.propertySourceNames.add(name);
}
@Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setIgnoreResourceNotFound(true);
configurer.setIgnoreUnresolvablePlaceholders(true);
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(new MockPropertySource());
configurer.setPropertySources(propertySources);
return configurer;
}
/**
* {@inheritDoc}
*
* Initializes the InMemoryUserDetailsManager with the following users:
*
* * user/password, role USER
* * admin/password, role ADMIN
*
* Neither the method {@link AuthenticationManagerBuilder#inMemoryAuthentication()}
* nor {@link AuthenticationManagerBuilder#apply(SecurityConfigurerAdapter)}
* are used to avoid to override the default UserDetailsService. Note that Springlets
* configure the JpaUserDetailsService as the default one.
*
* Use the passwords as given, they aren't encrypted.
*/
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
// clear credentials after success authentication
auth.eraseCredentials(securityProperties.getAuth().getInMemory().isEraseCredentials());
// Configure a in memory AuthenticationProvider with two users
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemAuthProvConfigurer =
new InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>();
String userPassw = UUID.randomUUID().toString();
inMemAuthProvConfigurer.withUser("user").password(userPassw).roles("USER");
String adminPassw = UUID.randomUUID().toString();
inMemAuthProvConfigurer.withUser("admin").password(adminPassw).roles("USER",
"ADMIN");
LOG.info("\n\nDefault security users [USERNAME : PASSWORD : ROLES]:\n" +
"\n [user : {} : ROLE_USER]\n" +
"\n [admin : {} : ROLE_USER, ROLE_ADMIN]\n", userPassw , adminPassw);
// Add users credentials to Environment for dev purposes
Map<String, Object> map = new HashMap<String, Object>();
map.put("springlets.security.auth.in-memory.enabled", true);
map.put("springlets.security.auth.in-memory.user.name", "user");
map.put("springlets.security.auth.in-memory.user.password", userPassw);
MutablePropertySources sources = this.applicationContext.getEnvironment().getPropertySources();
sources.addLast(new MapPropertySource("springlets", map));
inMemAuthProvConfigurer.configure(auth);
}
private void addOrReplace(MutablePropertySources environment,
PropertySource<?> result) {
if (environment.contains(result.getName())) {
environment.replace(result.getName(), result);
}
else {
environment.addLast(result);
}
}
@Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setIgnoreResourceNotFound(true);
configurer.setIgnoreUnresolvablePlaceholders(true);
MutablePropertySources propertySources = new MutablePropertySources();
MockPropertySource source = new MockPropertySource()
.withProperty("rabbitmq.port", "invalid");
propertySources.addLast(source);
configurer.setPropertySources(propertySources);
return configurer;
}
public static PropertySources create(ConfigGroup... configGroups) {
final MutablePropertySources sources = new MutablePropertySources();
for (ConfigGroup configGroup : configGroups) {
if (configGroup.isEnumerable()) {
sources.addLast(new ConfigGroupEnumerableResource(configGroup));
} else {
sources.addLast(new ConfigGroupResource(configGroup));
}
}
return sources;
}
@Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(
final ConfigurableEnvironment env)
{
final PropertySourcesPlaceholderConfigurer configurer =
new PropertySourcesPlaceholderConfigurer();
// https://jira.spring.io/browse/SPR-9631 may simplify this in
// future
final MutablePropertySources sources = new MutablePropertySources();
sources.addLast(createConfigPropertySource());
configurer.setPropertySources(sources);
configurer.setEnvironment(env);
return configurer;
}
@Override
public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
final Properties propertiesSource = new Properties();
final GetParametersByPathRequest.Builder requestBuilder = GetParametersByPathRequest
.builder()
.path(properties.getPath())
.recursive(true)
.withDecryption(true);
final GetParametersByPathResponse firstPage = ssmClient.getParametersByPath(requestBuilder.build());
addParametersToPropertiesSource(propertiesSource, firstPage.parameters());
String nextToken = firstPage.nextToken();
while (!isNullOrEmpty(nextToken)) {
final GetParametersByPathResponse nextPage = ssmClient.getParametersByPath(requestBuilder
.nextToken(nextToken)
.build()
);
addParametersToPropertiesSource(propertiesSource, nextPage.parameters());
nextToken = nextPage.nextToken();
}
final ConfigurableEnvironment env = beanFactory.getBean(ConfigurableEnvironment.class);
final MutablePropertySources propertySources = env.getPropertySources();
if (properties.isAddWithLowestPrecedence()) {
propertySources.addLast(new PropertiesPropertySource(PARAMETER_STORE_PROPERTY_SOURCE, propertiesSource));
} else {
propertySources.addFirst(new PropertiesPropertySource(PARAMETER_STORE_PROPERTY_SOURCE, propertiesSource));
}
}
@Bean(name = BASE_PACKAGES_PROPERTY_RESOLVER_BEAN_NAME)
public PropertyResolver dubboScanBasePackagesPropertyResolver(ConfigurableEnvironment environment) {
ConfigurableEnvironment propertyResolver = new AbstractEnvironment() {
@Override
protected void customizePropertySources(MutablePropertySources propertySources) {
Map<String, Object> dubboScanProperties = getSubProperties(environment.getPropertySources(), DUBBO_SCAN_PREFIX);
propertySources.addLast(new MapPropertySource("dubboScanProperties", dubboScanProperties));
}
};
ConfigurationPropertySources.attach(propertyResolver);
return new DelegatingPropertyResolver(propertyResolver);
}
private Map<String, Object> resolveSubProperties(boolean multiple, String beanName,
Map<String, Object> configurationProperties) {
if (!multiple) {
return configurationProperties;
}
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(new MapPropertySource("_", configurationProperties));
return getSubProperties(propertySources, environment, normalizePrefix(beanName));
}
@Test
public void configuresGemFirePropertiesCorrectlyAndSafely() {
Map<String, Object> gemfirePropertiesOne = MapBuilder.<String, Object>newMapBuilder()
.put("gemfire.cache-xml-file", "/path/to/cache.xml")
.put("gemfire.name", "TestName")
.put("gemfire.non-existing-property", "TEST")
.put("geode.enforce-unique-host", "true")
.put("enable-time-statistics", "true")
.put("junk.test-property", "MOCK")
.build();
Map<String, Object> gemfirePropertiesTwo = MapBuilder.<String, Object>newMapBuilder()
.put("gemfire.groups", "MockGroup,TestGroup")
.put("gemfire.mcast-port", " ")
.put("gemfire.remote-locators", "hellbox[666]")
.put("mock-property", "MOCK")
.put(" ", "BLANK")
.put("", "EMPTY")
.build();
CacheFactoryBean mockCacheFactoryBean = mock(CacheFactoryBean.class);
ConfigurableEnvironment mockEnvironment = mock(ConfigurableEnvironment.class);
EnumerablePropertySource<?> emptyEnumerablePropertySource = mock(EnumerablePropertySource.class);
Logger mockLogger = mock(Logger.class);
MutablePropertySources propertySources = new MutablePropertySources();
PropertySource<?> nonEnumerablePropertySource = mock(PropertySource.class);
propertySources.addFirst(new MapPropertySource("gemfirePropertiesOne", gemfirePropertiesOne));
propertySources.addLast(new MapPropertySource("gemfirePropertiesTwo", gemfirePropertiesTwo));
propertySources.addLast(emptyEnumerablePropertySource);
propertySources.addLast(nonEnumerablePropertySource);
when(mockEnvironment.getPropertySources()).thenReturn(propertySources);
Properties actualGemFireProperties = new Properties();
actualGemFireProperties.setProperty("remote-locators", "skullbox[12345]");
doAnswer(invocation -> actualGemFireProperties).when(mockCacheFactoryBean).getProperties();
doAnswer(invocation -> {
Properties gemfireProperties = invocation.getArgument(0);
actualGemFireProperties.putAll(gemfireProperties);
return null;
}).when(mockCacheFactoryBean).setProperties(any(Properties.class));
doReturn(mockLogger).when(this.configuration).getLogger();
doAnswer(invocation -> {
String propertyName = invocation.getArgument(0);
return gemfirePropertiesOne.getOrDefault(propertyName,
gemfirePropertiesTwo.getOrDefault(propertyName, null));
}).when(mockEnvironment).getProperty(anyString());
this.configuration.configureGemFireProperties(mockEnvironment, mockCacheFactoryBean);
assertThat(actualGemFireProperties).isNotNull();
assertThat(actualGemFireProperties).hasSize(4);
assertThat(actualGemFireProperties).containsKeys("cache-xml-file", "name", "groups");
assertThat(actualGemFireProperties.getProperty("cache-xml-file")).isEqualTo("/path/to/cache.xml");
assertThat(actualGemFireProperties.getProperty("name")).isEqualTo("TestName");
assertThat(actualGemFireProperties.getProperty("groups")).isEqualTo("MockGroup,TestGroup");
assertThat(actualGemFireProperties.getProperty("remote-locators")).isEqualTo("skullbox[12345]");
verify(mockLogger, times(1))
.warn(eq("[gemfire.non-existing-property] is not a valid Apache Geode property"));
verify(mockLogger, times(1))
.warn(eq("Apache Geode Property [{}] was not set"), eq("mcast-port"));
}
@Test
public void getConfiguredConnectionEndpointsIsCorrect() {
ConfigurableEnvironment mockEnvironment = mock(ConfigurableEnvironment.class);
MutablePropertySources propertySources = new MutablePropertySources();
Properties locatorProperties = new Properties();
Properties serverProperties = new Properties();
locatorProperties.setProperty("spring.data.gemfire.pool.locators", "boombox[1234], cardboardbox[5678], mailbox[9012]");
locatorProperties.setProperty("spring.data.gemfire.pool.car.locators", "skullbox[11235]");
locatorProperties.setProperty("spring.data.gemfire.pool.other-property", "junk");
serverProperties.setProperty("spring.data.gemfire.pool.servers", "mars[41414]");
serverProperties.setProperty("spring.data.gemfire.pool.swimming.servers", "jupiter[42424], saturn[43434]");
serverProperties.setProperty("spring.data.gemfire.pool.other-property", "junk");
propertySources.addLast(new PropertiesPropertySource("LocatorPoolProperties", locatorProperties));
propertySources.addFirst(new PropertiesPropertySource("ServerPoolProperties", serverProperties));
when(mockEnvironment.getPropertySources()).thenReturn(propertySources);
when(mockEnvironment.getProperty(anyString())).thenAnswer(invocation -> {
String propertyName = invocation.getArgument(0);
return locatorProperties.getProperty(propertyName, serverProperties.getProperty(propertyName));
});
List<ConnectionEndpoint> connectionEndpoints = this.condition.getConfiguredConnectionEndpoints(mockEnvironment);
List<String> connectionEndpointStrings = connectionEndpoints.stream()
.map(ConnectionEndpoint::toString)
.collect(Collectors.toList());
assertThat(connectionEndpoints).isNotNull();
assertThat(connectionEndpoints).hasSize(7);
assertThat(connectionEndpointStrings)
.containsExactlyInAnyOrder("mars[41414]", "jupiter[42424]", "saturn[43434]", "boombox[1234]",
"cardboardbox[5678]", "mailbox[9012]", "skullbox[11235]");
verify(mockEnvironment, times(1)).getPropertySources();
verify(mockEnvironment, times(4)).getProperty(anyString());
}
/**
* Customize the set of property sources with those contributed by superclasses as
* well as those appropriate for standard servlet-based environments:
* <ul>
* <li>{@value #SERVLET_CONFIG_PROPERTY_SOURCE_NAME}
* <li>{@value #SERVLET_CONTEXT_PROPERTY_SOURCE_NAME}
* <li>{@value #JNDI_PROPERTY_SOURCE_NAME}
* </ul>
* <p>Properties present in {@value #SERVLET_CONFIG_PROPERTY_SOURCE_NAME} will
* take precedence over those in {@value #SERVLET_CONTEXT_PROPERTY_SOURCE_NAME}, and
* properties found in either of the above take precedence over those found in
* {@value #JNDI_PROPERTY_SOURCE_NAME}.
* <p>Properties in any of the above will take precedence over system properties and
* environment variables contributed by the {@link StandardEnvironment} superclass.
* <p>The {@code Servlet}-related property sources are added as
* {@link StubPropertySource stubs} at this stage, and will be
* {@linkplain #initPropertySources(ServletContext, ServletConfig) fully initialized}
* once the actual {@link ServletContext} object becomes available.
* @see StandardEnvironment#customizePropertySources
* @see org.springframework.core.env.AbstractEnvironment#customizePropertySources
* @see ServletConfigPropertySource
* @see ServletContextPropertySource
* @see org.springframework.jndi.JndiPropertySource
* @see org.springframework.context.support.AbstractApplicationContext#initPropertySources
* @see #initPropertySources(ServletContext, ServletConfig)
*/
@Override
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME));
propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));
if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME));
}
super.customizePropertySources(propertySources);
}
/**
* Customize the set of property sources with those contributed by superclasses as
* well as those appropriate for standard servlet-based environments:
* <ul>
* <li>{@value #SERVLET_CONFIG_PROPERTY_SOURCE_NAME}
* <li>{@value #SERVLET_CONTEXT_PROPERTY_SOURCE_NAME}
* <li>{@value #JNDI_PROPERTY_SOURCE_NAME}
* </ul>
* <p>Properties present in {@value #SERVLET_CONFIG_PROPERTY_SOURCE_NAME} will
* take precedence over those in {@value #SERVLET_CONTEXT_PROPERTY_SOURCE_NAME}, and
* properties found in either of the above take precedence over those found in
* {@value #JNDI_PROPERTY_SOURCE_NAME}.
* <p>Properties in any of the above will take precedence over system properties and
* environment variables contributed by the {@link StandardEnvironment} superclass.
* <p>The {@code Servlet}-related property sources are added as
* {@link StubPropertySource stubs} at this stage, and will be
* {@linkplain #initPropertySources(ServletContext, ServletConfig) fully initialized}
* once the actual {@link ServletContext} object becomes available.
* @see StandardEnvironment#customizePropertySources
* @see org.springframework.core.env.AbstractEnvironment#customizePropertySources
* @see ServletConfigPropertySource
* @see ServletContextPropertySource
* @see org.springframework.jndi.JndiPropertySource
* @see org.springframework.context.support.AbstractApplicationContext#initPropertySources
* @see #initPropertySources(ServletContext, ServletConfig)
*/
@Override
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME));
propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));
if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME));
}
super.customizePropertySources(propertySources);
}
/**
* Customize the set of property sources with those contributed by superclasses as
* well as those appropriate for standard portlet-based environments:
* <ul>
* <li>{@value #PORTLET_CONFIG_PROPERTY_SOURCE_NAME}
* <li>{@value #PORTLET_CONTEXT_PROPERTY_SOURCE_NAME}
* <li>{@linkplain StandardServletEnvironment#SERVLET_CONTEXT_PROPERTY_SOURCE_NAME "servletContextInitParams"}
* <li>{@linkplain StandardServletEnvironment#JNDI_PROPERTY_SOURCE_NAME "jndiProperties"}
* </ul>
* <p>Properties present in {@value #PORTLET_CONFIG_PROPERTY_SOURCE_NAME} will
* take precedence over those in {@value #PORTLET_CONTEXT_PROPERTY_SOURCE_NAME},
* which takes precedence over those in {@linkplain
* StandardServletEnvironment#SERVLET_CONTEXT_PROPERTY_SOURCE_NAME "servletContextInitParams"}
* and so on.
* <p>Properties in any of the above will take precedence over system properties and
* environment variables contributed by the {@link StandardEnvironment} superclass.
* <p>The property sources are added as stubs for now, and will be
* {@linkplain PortletApplicationContextUtils#initPortletPropertySources fully
* initialized} once the actual {@link PortletConfig}, {@link PortletContext}, and
* {@link ServletContext} objects are available.
* @see StandardEnvironment#customizePropertySources
* @see org.springframework.core.env.AbstractEnvironment#customizePropertySources
* @see PortletConfigPropertySource
* @see PortletContextPropertySource
* @see PortletApplicationContextUtils#initPortletPropertySources
*/
@Override
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(new StubPropertySource(PORTLET_CONFIG_PROPERTY_SOURCE_NAME));
propertySources.addLast(new StubPropertySource(PORTLET_CONTEXT_PROPERTY_SOURCE_NAME));
propertySources.addLast(new StubPropertySource(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));
if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
propertySources.addLast(new JndiPropertySource(StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME));
}
super.customizePropertySources(propertySources);
}
@Test
public void testGetSubProperties() {
ConfigurableEnvironment environment = new AbstractEnvironment() {
};
MutablePropertySources propertySources = environment.getPropertySources();
Map<String, Object> source = new HashMap<String, Object>();
Map<String, Object> source2 = new HashMap<String, Object>();
MapPropertySource propertySource = new MapPropertySource("propertySource", source);
MapPropertySource propertySource2 = new MapPropertySource("propertySource2", source2);
propertySources.addLast(propertySource);
propertySources.addLast(propertySource2);
Map<String, Object> result = getSubProperties(propertySources, "user");
assertEquals(Collections.emptyMap(), result);
source.put("age", "31");
source.put("user.name", "Mercy");
source.put("user.age", "${age}");
source2.put("user.name", "mercyblitz");
source2.put("user.age", "32");
Map<String, Object> expected = new HashMap<String, Object>();
expected.put("name", "Mercy");
expected.put("age", "31");
assertEquals(expected, getSubProperties((Iterable) propertySources, "user"));
assertEquals(expected, getSubProperties(environment, "user"));
assertEquals(expected, getSubProperties(propertySources, "user"));
assertEquals(expected, getSubProperties(propertySources, environment, "user"));
result = getSubProperties(propertySources, "");
assertEquals(Collections.emptyMap(), result);
result = getSubProperties(propertySources, "no-exists");
assertEquals(Collections.emptyMap(), result);
}