I have below code:
#Value("${XXX.Run.Flag}")
private String xxxABC;
I am reading the value of XXX.Run.Flag from my config.properties file.
Now whenever i make change in the value of this key in my config files, it do not get reflected until and unless i restart the server. I am aware that Annotations gets initialised during the application start up.
I do not want to restart the server if i make any change in the annotation key value. Can someone suggest me how to do this.
I am using Portlet Spring MVC 3.0.
You may want to consider Spring cloud config server , it does offer a lot including what you are asking for
#RefreshScope for Spring #Beans that want to be re-initialized when configuration changes,
I'd recommend to use net.unicon.springframework.addons.properties.ReloadablePropertiesFactoryBean as described here
Related
I am currently creating a Java Spring application that works with the spring security JWT. Everywhere I look and read about the "secret string", it says should be changed in production. Like this line in my application.properties: security.jwt.secret="this-is-a-512-bit-key-used-for-signing-jwt-tokens-that-should-be-changed-production"
As well as in stackoverflow question that are sort-of related like this one here: How to include jwt secret in application.yaml for Java Spring.
My question is, what should that string become in production? Am I supposed to generate this somewhere in a SecurityConfig class? Or should I generate a 512 bit string and just paste that in the application.properties file?
Thanks in advance.
Secrets should not be added in your regular application.properties file because that would be checked into your version control system. There are various ways to externalize configuration but the easiest is usually to define environment variables.
In your case, you would need an environment variable called SECURITY_JWT_SECRET and Spring Boot will pick this up automatically.
One way to change properties of a spring app is using Spring Cloud Config. Basically your config is in a GitHub repo and as soon as you modify, Spring cloud config server propagates it to other applications referencing it through application.properties.
https://cloud.spring.io/spring-cloud-config/reference/html/
I will share how it has been done in our application which I think one of the standard way of storing credentials.
There may be alternate ways also.
Its not ideal to store token or credentials in properties
We can externalize the token into Vault or config server
when server starts spring application can fetch the properties
Access to vault are controlled
As we have different vault servers across environments, we can store and change the token in runtime and refresh the application.
Regarding generating the jwt token, it should have some expiry time and refreshed periodically.
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
Currently i am working on a REST based project in Spring Boot.
I have added the api url in 'application.properties' file.
i.e.
application.properties
api-base-url=http://localhost:8080/RestServices/v1
And also this 'api-base-url' value access from java.
In some situations i need to change the 'api-base-url' dynamically.
I have change 'api-base-url' value dynamically & working fine.
But my problem is that
when wildfly restart then the configuration will be reset to default.
i.e
This is my default value
api-base-url=http://localhost:8080/RestServices/v1
dynamically change to
api-base-url=http://10.34.2.3:8080/RestServices/v1
when wildfly restart then the configuration will be reset to default.
i.e.
api-base-url=http://localhost:8080/RestServices/v1
Have any solution for this?
You might want to consider using a cloud config server to host your config. Two examples are Spring Cloud Config and Consul.
These servers will host your application's configuration and your spring boot application will make a call out to the config server on start up to get it's config.
spring-boot-actuator exposes the endpoint /refresh which forces the application to refresh it's configuration. In this case, it will call out to the config server to get the latest version.
This way you can change the config hosted in the config server then hit the /refresh endpoint and the changes will be picked up by your application.
As #moilejter suggests, one possible way is to persist in database table and at start time you simply read from that table instead of application.properties file. Your application.properties files can hold information necessary for database connection.
You would also need a JMX method or a REST API to trigger in your application that the url has changed and which inturn, would simply read from same table. This way you would be safe even if app restarts and you won't lose the override.
You can use BeanFactoryPostProcessor coupled with Environment bean to leverage spring placeholder concept.
#user2214646
Use spring expression language
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.
I want to configure a self-written JCA 1.6 inbound resource adapter (RA). My big problem is that the RA needs to get access to some (dynamic) configuration data living in the application that uses the RA.
Now I know that this is against the original idea of the whole JCA idea but unfortunately I cannot change this design as quickly as I'd like/have to.
The data I need to get to the RA is
the port it's supposed to listen on,
the license used for the whole application (the feature the RA supplies requires extra licensing)
additional configuration data stored in a db
I've come up with four ideas:
Use the asadmin create-resource-adapter-config. Due to the fact that glassfish doesn't seem to restart apps depending on the RA, we need to restart the application after this. While this attempt is suitable for the port, it won't fit for the other data.
Use administered objects to give my application a means to pass data in to the RA. This idea is mentioned here. I guess this does it, but the spec states in chapter 13.4.2.3 that
Note, administered objects are not used for setting up asynchronous message
deliveries to message endpoints. The ActivationSpec JavaBean is used to hold all
the necessary activation information needed for asynchronous message delivery
setup.
But I cannot get any dynamic data to the ActivationSpec object (neither through a DeploymentDescriptor nor through annotations). Or did I miss something here? :-)
Use JDBC directly to access the data (also grabbed the idea from here). While this is presumably the best idea, it does not work for the mentioned licensing data as it is not stored in the db.
The last idea I had was to put a method in the MessageDrivenBean (through my interface) that is used to fetch data from within the RA. That method could be called from the RA and would supply the data. But: I just think that is quite abusive as it couples the RA to the app.
Dear community, what are your thoughts on this one? I'm afraid it's not so easy to find answers to these questions, so I'd be quite happy about opinions!
Thanks and cheers,
Julius
In the ra.xml there is the possibility to define config-properties. In Websphere these then show up as editable fields in a table of custom properties for the selected resource adapter. I'm working on a similar problem, I also need to pass hostname / port info to an RA. Unfortunately I haven't figured out how to read the contents of these fields from within the RA however.
The solution I finally came up with is to use the #ConfigProperty annotation. This means I use option one of my question above.
So my ResourceAdapter class looks like this:
public class Hl7ResourceAdapter implements ResourceAdapter {
#ConfigProperty
private Integer port = null;
// Rest from ResourceAdapter interface omitted here...
// Use port here to open socket...
}
The #ConfigProperty fields can now be set through either
a resource-adapter-config
the ra.xml deployment descriptor
Now in order to reconfigure these settings I use glassfish's REST interface to change these settings programmatically (one could also use the asadmin create-resource-adapter-config command). I circumvent the problem, that glassfish does not restart the application that uses the resource adapter by simply restarting it myself through REST. (To be precise: I disable the application and then reenable it to get around another bug in glassfish)
A few additional notes:
We deploy the resource adapter's .rar file into the .ear of the application using it.
We have a separate application outside glassfish (standalone) that calls the REST interface to do such things as restart the resource adapter application etc. It is obvious that an application cannot restart itself properly.
Hope this helps. kutuzof, will this get you any further?