Spring and WildFly Infinispan cache lookup - java

I have implemented caching in my Spring application and when I run it locally everything works fine. I have infinispan.xml configuration in resources and the following configuration:
spring.cache.type=infinispan
spring.cache.infinispan.config=classpath:infinispan.xml
Now I would like to deploy it to WildFly 10 and to use built in cache. I have defined my cache container with jndi-name=infinispan/CONTAINER.
I tried setting spring.cache.infinispan.config to:
infinispan/CONTAINER
java:/infinispan/CONTAINER
java:jboss/infinispan/CONTAINER
But I allways get the following error:
java.lang.IllegalArgumentException: Cache configuration does not exist
What should I do make this work?

As far as I know, this is not possible at the moment.
You will need to extend SpringEmbeddedCacheManagerFactoryBean and override #createBackingEmbeddedCacheManager() method. Then use JndiTemplate to grab a reference to EmbeddedCacheManager deployed in WildFly (similarly to this thread).
I also created ISPN-7208 to allow specifying JNDI references for Cache Managers.

Related

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

Dynamically change application.properties values in spring boot

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

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.

How to implement environment-specific init parameters in my tomcat application

I'd like to be able to implement a configuration-less deployment for my java application (tomcat7, spring-mvc). For example, right now we are considering creating one context.xml file for each environment (prod, stage, dev) we deploy to:
context_prod.xml
context_stage.xml
context_dev.xml
context.xml (for localhost)
On each of our servers we would have a symlink context.xml which would point to the appropriate context file (e.g. context_prod.xml). So when we deploy, we don't have to worry about changing database references, keys, etc.
I feel like there's probably a better way to do this; perhaps one that is built into spring?
Spring has recently added the functionality to handle environment configuration:
http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/
This still seems a little bit complicated for me and I have done exactly what you are asking in my own Spring MVC applications for our logging. In my DispatcherServlet configuation I have this line:
<context:property-placeholder location="classpath*:/system.properties"/>
<util:properties id="mySystemProperties" location="classpath:/logging/log4j-${system.runMode}.properties" />
system.runMode is just an env variable that we created and is set in CATALINA.SH at startup like this: Setting environment variable TESSDATA_PREFIX in Tomcat
I then use Spring EL to reference any values I want and it works per environment. As you can see I did this for our logging and have a different logging configuration file per environment.
You could use Spring #Profile introduced in Spring 3.1. In your case you could use profiles like dev, stage, prod etc.
This profile value could be initialized run time. So when your application started, Spring could fetch appropriate profile based on configuration.
You could setup profile from environment variable, via deployment descriptor (web.xml) etc. This Spring source tutorial could be interesting for you.
I personally using Maven build to replace the profile value during build time in the web.xml. In the build time I passed profile value as build argument.

Lazy init doesn't work in Spring MVC 3

I'm facing a problem with Spring dependency injection. I have an application that once deployed checks if it's previously configured, if not then it launches configuration manager and asks the user for db host, port, admin login and pass etc.
Now I can't find a way to inject those configured values. I assume that I would have to use lazy init beans but when i add the annotation #Lazy, Spring is still trying to inject them at the runtime and I'm getting an error since the host and port are not yet configured.
What am I missing :/?
You need a lookup method, a feature accessible only through XML configuration. There is an almost ancient JIRA issue still open on this, still unresolved.
Please do check this comment on the mentioned issue, it describes a workaround that may be an option for you.

Categories

Resources