reflect property file changes in osgi bundle without restarting Karaf Server - osgi

How can i configure my Karaf Server in such a way that whenever there is a property file change, i should not restart my server for getting those changes in staead it should atomatically detect thos changes. I deploying my bundle in osgi Karaf Server. For loading property file i am using below configuration in my camel context.
<bean
class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer"
id="properties">
<property name="locations">
<list><value>file:etc/app/properties/env/env.properties</value>
<value>file:etc/vrol/security/ssl.properties
</value></list></property></bean>

You are currently not using an OSGi mechanism to load the property file. As far as I know you can only achieve this by switching from spring to blueprint.
In blueprint you can define a config like this:
<cm:property-placeholder persistent-id="myconfig" update-strategy="reload" >
</cm:property-placeholder>
This will load the config from etc/myconfig.cfg and will reload the blueprint context when the config changes.

Related

Create Externalized Configuration in spring-boot along with profiles

I have a spring-boot application with annotations instead of context.xml.
In my src/main/resources folder I have: application-dev.properties and application-test.properties.
which work perfectly for different profiles (while running with VM option like -Dspring.profiles.active=dev)
Now I need to externalize this properties with file in /opt/software/Tomcat8/conf/app.properties
Some props override each other, some don't.
in Tomcat config context.xml I say:
<Environment name="app.properties"
value="file:///opt/software/Tomcat8/conf/app.properties"
type="java.lang.String" override="false"/>
How to use it via JNDI in my application configuring app with no XML but annotations in Spring-bot application class?
I need it to have priority to inner jar properties according to
Link to Spring-boot.doc
One solution I found was to have the vm argument -Dloader.path with the external path when executing the application. Please keep in mind if you're using a fat jar you may need to create the package in Zip model, otherwise it will not work.

Spring customised PropertyPlaceholderConfigurer

I have config xml based spring application for which I have moved proprties required at start up time in database. It was very difficult to manage hundreds in property file and that is why database is introduced. To read properties a spring restful service is developed to return a map of all properties required at start up time.
I want to know how to replace properties reading from a map to spring context file e.g. ${config.service.url} should be polulated from a map read via web service.
One option I considered is to upgrade to Annotation based and start using MapPropertySource and Environment interface as environment.getRequiredProperty("config.service.url"). However upgrading to Annotation based is a big impact on project and is no at this time.
Second option that I am looking forward is to have a customised PropertyPlaceholderConfigurer.
Any pointer/help on this will be great.
Cheers,
Amber
You could define a PropertyPlaceholderConfigurer, but instead of specifying a file location, you can pass the properties directly as returned by your restful service.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" .../>
</bean>

OSGi bundle read config properties

I have config.properties in my OSGi bundle. but the OSGi bundle can not read it.
Application context refresh failed (OsgiBundleXmlApplicationContext(bundle=dao, config=osgibundle:/META-INF/spring/*.xml))
org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException
I am using Spring to read the config.properties
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="config.properties" />
</bean>
It seems like the OSGi only reads the .xml file.
Does someone has any idea?
You have to specify the correct resource for your value property.
There are some built in implementations, like:
ClassPathResource: value="classpath:/META-INF/config.properties"
FileSystemResource: value="file:C:/foobar/config.properties"
If you want to place the file outside the library you can use a system property (e.g. -DpropertyFile=C:/loremIpsum/config.properties) to specify the path, like
value="file:${propertyFile}"
since Spring 3.0.? even with default value
value="file:${propertyFile:C:/foobar/config.properties}"
(Have a look at your OSGi framework on how to set a system property. I am also not sure if the ClassPathResource works well / is recommended in OSGi environments.)

How to configure JSF 2.0 application's project stage via JNDI in Tomcat

been struggling to find a way to configure Tomcat 7.0.11 so that my web application would use project stage setting from Tomcat's config. So far - no luck. The idea is to set this property in Tomcat server/host/application wide but not to set it in web.xml. Any ideas? I am using MyFaces JSF 2 implementation 2.0.5.
The specification says that the JSF implementation looks up the Project Stage using JNDI under java:comp/env/jsf/ProjectStage. If not found it uses the context parameter javax.faces.PROJECT_STAGE from your web.xml. This means that if defined/found on your Tomcat using JNDI, the value of preferred over the web.xml setting.
There are two things you can do:
Option 1: Overwrite the context parameter: This means that context parameter is set/overwritten using the Tomcat server.xml or context.xml. You need to put this in your <Context>-tag:
<Parameter name="javax.faces.PROJECT_STAGE" value="Production" override="false" />
Careful: override="false" here means that this parameter can NOT be overriden by the web.xml (not the other way around)!
Option 2: Configure a resource that can be found using JNDI: By using this that JSF implementation can resolve the project stage using the JNDI lookup.
<Environment name="jsf/ProjectStage" value="Production" type="java.lang.String" override="false"/>
You can also move this to the <GlobalResources>-tag in your server.xml. In this case you would need to reference this in your <Context>-tag by using <ResourceLink>-tag.

Where to store database passwords in a spring application or use JNDI?

Seems like a simple task. I have a webapp which requires a database connection. I'd like to be able to drop an updated .war file on this app server and load a new version without having to re-edit an applicationConfig.xml file to specify the database connection parameters for production.
Is using the container to setup the data source and then referencing it from JNDI the preferred way to go? I think it is cleaner having it all defined in the spring .xml file, but I can't come up with a clean way to allow the production password to be set only once as we roll out new versions.
So, how do you specify your database connection information in a spring application so that you can upgrade it without having to re-edit the files?
If you use JNDI, how do you handle setting up of your tests since the JNDI is not going to be available outside of the container?
Thanks!
The typical way to externalize database connection properties is to store them in a .properties file and load using <context:property-placeholder .../> . Then you can have different .properties files for testing and production.
If you choose JNDI, you can use a Spring's mock JNDI support for testing.
One approach is for your Spring configuration file to be composed of fragments related to specific layers in your application.
One such fragment could contain your DataSource defintion. For production, this fragment would use a jee:jndi-lookup. And then for test, have a different fragment would use a DriverManagerDataSource ?
Update:
If you want to change the datasource after deployment, then you can use this technique, along with changing the which datasource is injected into your other beans using a PropertyPlaceholderConfigurer as explained in an old post I wrote
eg:
<bean class="foo.bar.SomeClassNeedingDataSource"">
<property name="dataSource" ref="${the.datasource.to.inject}" />
</bean>
<jee:jndi-lookup id="jndiDataSource" ... />
<bean id="driverManagerDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
...
</bean>
# the properties file
the.datasource.to.inject = jndiDataSource
#the.datasource.to.inject = driverManagerDataSource

Resources