How to Instantiate #configuration bean based on request parameters in java spring? - java

I have multiple configuration files in java spring.
I need to instantiate it based on the request parameters.
Is there any way to do it?
Thanks in advance!!
Sakthi

This is not possible, as Spring initializes the configuration before the service starts (or more accurate, when it starts) so when you get a request, it is too late - the configuration is already built.
You can, however, control it with spring profiles- either via env variable on the machine or arguments passed to the jvm when you run your app. This way you can control which spring profile to use and set the configurations per profile.

Related

How to deactivate a url in a specific profile in quarkus?

I am developing an API with quarkus 1.11. I would like to make a call to another API but only locally I don't want it to be called in production.
I know what I can do:
ProfileManager.getActiveProfile() != "test"
But I would like to know if it is possible to configure it with some java annotation or in the aplication.properties as:
%dev.test.api/mp-rest/url=DISABLED
Thank you so much!
With the configuration properties and the MP-restclient you cant deactivate and endpoint, only change the url to a different one.
But what you can do instead is create a configuration property similar to the one you suggested, then inject the property in your code and use it to call or not your endpoint, It is similar to the logic you do the profile manager, but you will have more control over the invocation.
For example this could be the properties.
%dev.test.api.enabled=true
%prod.test.api.enabled=false
Then inject the properties like in this example using the injection capabilities of quarkus and cdi.
Then implementing the condition to check if the call must be made or not.
I think that you will not find any property to do not make a call, because at the end you are executing a method and waiting for an answer, and this behaviour cannot be altered by an endpoint property, only by code offering an alternative response or execution path.

How to load changed environment variable in spring boot application running in PCF without restarting application?

We have a spring boot application running in PCF and it reads the PCF environment variables(CF_INSTANCE_INDEX, CF_INSTANCE_ADDR,..) from an application. Based on those variables, we are trying to implement the logic for a scheduler. While running this scheduler, these variables' values could have changed. Is there a way to refresh/reload bean that have env values during runtime?
we used #RefreshScope annotation on config properties bean.
#Configuration
#RefreshScope
public class PcfEnvProperties{
#Value("${CF_INSTANCE_INDEX}")
private int intanceIndex;
#Value("${CF_INSTANCE_ADDR}")
private String intanceAddr;
...
}
and refresh using
context.getBean(RefreshScope.class).refresh("PcfEnvProperties");
PcfEnvProperties pcfEnv = context.getBean(PcfEnvProperties.class);
But It is not loading the recently changed env variable into running application. Any ideas on how to accomplish this?
You can use Spring Cloud Config Server in combination with Spring Actuator to expose an endpoint in your service that will refresh the application's properties on the fly. You could set up your scheduler to hit this endpoint on a timer or as needed.
Here is one tutorial I found that seems pretty straightforward: https://jeroenbellen.com/manage-and-reload-spring-application-properties-on-the-fly/
You may have to play with the setup depending on how your platform is configured, but I believe it should do what you're wanting. We have deployed many java web services on our PCF platform using this actuator/config server approach, and we can just make a call to the refresh endpoint and it successfully pulls in (and overwrites when necessary) the new properties and values from the config server. Also you can pull out a list of the property names and values that changed from the response.
I'm not familiar with the specific property values you mentioned, but as long as they are normally a part of Spring's ApplicationContext (where properties usually are found) then you should be able to pull in changed values using this approach with Spring's cloud config server and actuator libraries.
Hope this helps

How to update configuration of SpringBoot application at runtime without reloading whole ApplicationContext

I am trying to figure out how can I dynamically update/reload externalized configuration in a Spring Boot application without restarting the whole application.
Most of the advice involves reloading ApplicationContext after changing the externalized configuration, but that is equivalent to restarting the entire application, so this is not really all that useful.
Reading through SpringBoot reference documentation, I found a chapter 23.7 Typesafe Configuration Properties.
If I understand it correctly, this allows to define simple POJO classes that will hold your application (externalized) configuration values as attributes.
In theory at least, this scheme could be used to bind beans only once to the required configuration POJO and upon configuration change just update the values in the POJO. Components could easily pick up the changes next time they access getters on the POJO...
However, I have yet not managed to figure out how to enable this type of behavior. Is there some glaringly obvious way to dynamically update components annotated with #ConfigurationProperties when relevant configuration has changed?
It sounds like you're looking for #RefreshScope which is provided by Spring Cloud. From the Spring Cloud documentation:
A Spring #Bean that is marked as #RefreshScope will get special treatment when there is a configuration change. This addresses the problem of stateful beans that only get their configuration injected when they are initialized. For instance if a DataSource has open connections when the database URL is changed via the Environment, we probably want the holders of those connections to be able to complete what they are doing. Then the next time someone borrows a connection from the pool he gets one with the new URL.

Production vs staging - adding staging specific controllers

We are using spring with a tomcat 7 cluster for our web application.
In order to do an load testing our staging server we need to have some sort of a "special controller".
This controller is providing some really risky operations that must not reach the production server!
What is the best way to do this? how can we create this code, add it to our svn, and still make it unavailable to production deployment?
Thanks
I'd suggest using Spring profile. You can set a bean to load only when a specific profile is active. This way this controller would load only when profile staging is active.
For example you can define:
#Controller
#Profile("staging")
public class SpecialController {
...
}
You need to pass in the JVM options the profile -Dactive.profiles=staging
Spring has special feature for this named "profiles". You can define staging profile, create as many beans as you need marked for this profile. Then, when you are running application you just have to supply JVM option -Dspring.profiles.active=staging and all staging targeted beans will run. Otherwise they will be ignored.

Different bean configuration depending on runtime?

I have a bean, say manager, which is used all over my application for remoting. The bean is using httpclient which in turn can be configured with or without proxy. But this configuration can be only one. What i want in my application is: when the application started, the user is asked does she want to use a proxy or not? And depending on the user's answer the bean is properly configured and only then started. Some sort of dynamic configuration during runtime.
Is it possible or maybe I should achieve this some other way?
Thank you.
Why can't you call setProxy() on httpclient configuration depending on user's input?
Alternatively you can configure httpclient as bean in Spring context (either directly or create a simple wrapper) two times - one with proxy and one without. Then manager can choose which one to use depending on user's input (both can be injected into manager).

Categories

Resources