It would be even possible to do this?
I need to deploy a spring cloud config server with property files inside the container, so I need to use the native profile, BUT in the company only allows certain profile names when running the applications.
There is a way to do some manual configuration to make a custom profile behaves like the native one?
Thanks!
Thanks #spencergibb !
This just works:
#EnableConfigServer
#SpringBootApplication
public class BrokernetConfigApplication {
public static void main(String[] args) {
SpringApplication.run(BrokernetConfigApplication.class, args);
}
#Bean
public NativeEnvironmentRepository nativeEnvironmentRepository(
NativeEnvironmentRepositoryFactory factory,
NativeEnvironmentProperties environmentProperties) {
return factory.build(environmentProperties);
}
}
Related
I have a quarkus application which is a main app. Here is an simplified example:
#QuarkusMain
public class MyXYZTool {
public static void main(String... args) {
Quarkus.run(MyXYZTool.class, args);
}
public static class CacheApp implements QuarkusApplication {
#Inject
AgroalDataSource dataSource;
#Override
public int run(String... args) throws Exception {
readCommandLineParameter(args);
//and so on...
return 0;
}
}
};
I have also an application.properties which contains the credentials to access to an Azure cloud blobstorage.
Secrets.BlobStorages.xyz.ConnectionString=abcaccesstoken
I start my app from command line like this:
//start from command line
java -jar ./target/xyz-runner.jar
My app works also so far.
But I want to hand over the credentials to access an Azure cloud blob storage over the command line. It should not be hardcoded in the application.properties. This has security reasons.
I ask me how I can hand over Secrets.BlobStorages.xyz.ConnectionString over the command line and activate this.
Can somebody help me?
I have found an answer to my question by this webside from Quarkus:
https://quarkus.io/guides/config#overriding-properties-at-runtime
I tried it out and it works.
I have a project in Spring Boot (1.5.9). I have properties in an application.properties in src/main/resources and in an external application.properties. I also can provide values through the command line.
My main class looks like this:
#SpringBootApplication
#SpringBootConfiguration
#EnableJpaRepositories
#EnableEncryptableProperties
#Import(RepositoryRestMvcAutoConfiguration.class)
public class Application {
public Application() { super(); }
public static void main(String[] args) {
final SpringApplication app = new SpringApplication(Application.class);
app.run(args);
}
}
I have a different class that looks something like this:
#Component
public class MyAuthenticationProvider extends AuthenticationProviderInterface {
#Value("${myproject.authentication.url:https://blah:8443}")
private String authenticationURL = "https://test.blah:8443";
#Override
public void afterPropertiesSet() {
System.err.println(authenticationURL);
}
..... other stuff.....
}
From the System.err, I get https://test.blah:8443.
Now, I can get all of my major variables: spring.main.banner-mode, spring.datasource.name, etc. I just do not seem to be able to get my custom variables--myproject.authentication.url or myproject.authentication.accessstring.
The spring variables are behaving as expected--I can follow precedence from the properties files to the command line. It's only the custom variables that are giving me fits.
Does anyone have any suggestions? I'm trying to give good information, but I am typing between two unconnected computers and I will occasionally have a typo.
Thank you.
Change #Comopnent to #Component.
OK. This was blatant stupidity and Eclipse "helping" me again. The Save actions added a "final" and (unsurprisingly) the values were not being updated. Sorry for wasting people's time.
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
Java Application
JUnit
Servlet Container
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.
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);
}
}
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)
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);
}
}
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.
Is there some reliable way how to check if spring boot is running in JAR (standalone with embedded tomcat) or WAR (in j2ee server) mode?
There's no built in API to check which environment you're running in. Probably the most robust way would be to use different configuration for your application depending on whether it's started via its main method or via its SpringBootServletInitializer subclass. Exactly what you should do depends on your reason for needing to know and also personal preference.
For example, you could configure a property that you can the query via the Environment, using #Value, etc:
#SpringBootApplication
public class ExampleApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ExampleApplication.class).properties(
"com.example.mode:servlet-container");
}
public static void main(String[] args) throws Exception {
new SpringApplicationBuilder(ExampleApplication.class).properties(
"com.example.mode:standalone").run(args);
}
}
Another option would be to provide a configuration class in addition to ExampleApplication.class that's different depending on what mode you're running in:
#SpringBootApplication
public class ExampleApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ExampleApplication.class,
ServletContainerConfiguration.class);
}
public static void main(String[] args) throws Exception {
new SpringApplicationBuilder(ExampleApplication.class,
StandaloneConfiguration.class).run(args);
}
}
Exactly what you do in ServletContainerConfiguration or StandaloneConfiguration is then up to you. You could, for example, publish a bean that remembers the mode and then query it whenever you need to know.
Yet another option would be to activate different profiles depending on the mode.
1.
I'm working with Spring Boot. My Main class very simple
#ComponentScan
#EnableAutoConfiguration
#Configuration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
#2. Now I would like to make my static content externalised into a jar file. So, below is the jar project
/pom.xml
/src/main/resources/META-INF/resources/hello.json // here is my resource
I do maven install and put the dependency into the main app, run the app normally. Now I can invoke http://localhost:8080/hello.json to get my hello.json file
#3. Then, the next step is using the Apache Tiles for my main web project, so I create a #EnableWebMvc class to configure the tilesViewResolver
#Configuration
#EnableWebMvc
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
public #Bean TilesViewResolver tilesViewResolver() {
return new TilesViewResolver();
}
public #Bean TilesConfigurer tilesConfigurer() {
TilesConfigurer ret = new TilesConfigurer();
ret.setDefinitions(new String[] { "classpath:tiles.xml" });
return ret;
}
}
Then I started again the application and try the hello.json to ensure everything still works properly. But, the 404 page appear. Delete the WebMvcConfiguration give back my hello.json.
What configuration I should do to resolve this issue?
Thanks a lot.
In Spring MVC, using XML configuration, you have to have a tag like the following to service static content:
<mvc:resources mapping="/js/**" location="/js/"/>
This insinuates that Spring Boot is doing something to automatically guess that you have static content and properly setup the above example in META-INF/resources. It's not really "magic", but rather that they have a default Java Configuration using #EnableWebMvc that has some pretty reliable default values.
When you provide your own #EnableWebMvc, my guess is you are over-writting their "default" one. In order to add back a resource handler, you would do something like this:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(31556926);
}
This is equivalent to the XML above.