Reputation: 91
I want to set active profile host dependent for any envrionment and cannot find an environment independent hook.
Following factory will set the active profile before application context will build.
/META-INF/spring.factories
org.springframework.context.ApplicationContextInitializer=MyApplicationContextInitializer
MyApplicationContextInitializer.java
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext ca) {
ConfigurableEnvironment environment = ca.getEnvironment();
environment.addActiveProfile("myHost");
}
}
If this example is executed in a mock environment by JUnit ...
*Test.java
...
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
...
... following will be logged.
...
... RestControllerTests : The following profiles are active: myHost
...
but profile myHost is not active and default profile will be used in context of JUnit!
A test as Java Application and JUnit with VM arguments works ...
-Dspring.profiles.active=myHost
I use a war packaged spring-boot-starter-web app and programmatically profile shall be set and used in any environment
How do I set the profile programmatically for any environmnet?
I do not want to use VM arguments or environemt variables because the profile shall be set by the current host name.
Upvotes: 7
Views: 19391
Reputation: 1529
Don't you think that could be achieved with an EnvironmentPostProcessor ans still have an impact on the running environment? My attempts failed.
@Order(Ordered.LOWEST_PRECEDENCE)
public class EnvtPostProcessor implements EnvironmentPostProcessor {
@SuppressWarnings("deprecation")
@Override
public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication application) {
if ((env.acceptsProfiles("bar1") || env.acceptsProfiles("bar2"))
&& !(env.acceptsProfiles("foo1") || env.acceptsProfiles("foo2"))) {
env.addActiveProfile("foo1");
}
}
}
NB: don't forget to register the processor in src/main/resources/META-INF/spring.factories:
org.springframework.boot.env.EnvironmentPostProcessor=com.mygroup.myapp.EnvtPostProcessor
When I only apply the "bar2" active profile, the "foo1" profile is added to the environnement as an active profile, before application context initialization; but not all beans are found eventually (as they are in the originally complete active profiles list use case).
Maybe that's because of the dependencies (Azure for Spring Cloud connection, by the way) : I end up with no OAuth2UserService found for my ActiveDirectoryConfigurer.
Upvotes: 0
Reputation: 4524
I don't think there is such a thing as setting active profile dynamically (programmatically) at runtime once the application is running, any modification to the profile will not have any effect on the loaded beans and properties files.
However, before running the application you can configure the available profiles of the application. for example:
@SpringBootApplication
public class DemoApplicationWithSysProperty {
public static void main(String[] args) {
System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME,
PROFILE_NAME);
SpringApplication.run(DemoApplicationWithSysProperty.class, args);
}
}
Upvotes: 1
Reputation: 141
Simplest answer after a lot of googling :)
@SpringBootApplication
public class ExampleMain2 {
public static void main(String[] args) {
ConfigurableEnvironment environment = new StandardEnvironment();
environment.setActiveProfiles("dev");
SpringApplication sa = new SpringApplication(ExampleMain2.class);
sa.setEnvironment(environment);
sa.setAdditionalProfiles("remote","live");
sa.run(args);
}
}
Upvotes: 14
Reputation: 6474
I had the same issue and I finally solved it implementing the ActiveProfilesResolver interface.
In your case you could do something like this:
public class MyActivateProfilesResolver implements ActiveProfilesResolver {
@Override
public String[] resolve(Class<?> testClass) {
// some code to find out your active profiles
return new String[] {"myHost"};
}
}
And then you need to link your test with your resolver like this:
@ActiveProfiles(resolver = MyActivateProfilesResolver.class)
Upvotes: 6