I have an application.yml file with following structure
app:
tenants:
default:
property1: 1
property2: 2
property3: 3
features:
feature1: true
feature2: false
tenant1:
property1: 5
features:
feature2: true
tenant2:
property3: 9
and following @ConfigurationProperties
classes
@ConfigurationProperties("tenants")
class TenantsProperties {
Map<String,Tenant> tenants
}
class Tenant {
int property1 = 0;
int property2 = 0;
int property3 = 0;
Map<String,Boolean> features = new HashMap<>();
}
I want to default the properties of tenant1
and tenant2
on what is in the default
tenant.
@SpringBootTest
public class TenantsProeprtiesTest {
@Autowired
TenantsProperties tenants;
@Test
void test_default_properties() {
Tenant tenant = tenants.getTenants().get("tenant1");
assertEquals(2, tenant.getProperty2());
assertEquals(5, tenant.getProperty1());
}
}
I've registered a custom EnvironmentPostProcessor
@Order
public class DefaultTenantPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
Map<String,Object> defaultProperties = getProperties("app.tenants.default", environment);
Set<String> tenants = getDefinedTenants(environment);
Map<String,Object> properties = combineTenantsAndDefaults(tenants, defaultProperties);
environment.getPropertySource().addLast(new MapPeropertySource("defaultTenantProperties", properties);
}
...
}
The EnvironmentPostProcessor
works and adds properties to the end of the list, however by the time it gets to the test, the properties defined in the yaml file get moved beyond that, so they have lower precedence than the properties generated via the post processor and assertEquals(5, tenant.getProperty1());
fails.
Edit: so I did a bit of debugging and my default tenant properties get "upstaged" in org.springframework.boot.test.context.ConfigDataApplicationContextInitializer
via ConfigDataEnvironmentPostProcessor.applyTo(environment, applicationContext, bootstrapContext)
. At the moment I have no idea how to work around this.