How to load a secret.properties file in apacheignite/docker stock image - spring

I used gridgain’s webconsole to create a configuration file for my ignite node (ignite-config.xml). I’d like to see if I can get this running in apache’s docker ignite image (apacheignite/ignite). I’ve created a volume in my compose file that maps to a config folder that houses my ignite-config.xml.
I need to include the secret.properties (that has my jdbc url/username/password) file as well so I put it in the config folder too.
When I do a docker-compose up I get a java.io.FileNotFoundException: class path resource [config/secret.properties] cannot be opened because it does not exist]
This is the part of the xml config that deals with the secret.properties location:
<!-- Load external properties file. -->
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:secret.properties"/>
</bean>
What do I need to change so that the secret.properties file in the config folder is loaded? Is there a better way to do this?

I do not know how to easily deploy the secret.properties file without going through a full build and deploy, but in order to get past that for testing purposes, you could get rid of the secret.properties and use environment variables instead.
Which might look something like this for a JDBC connection to Postgres:
<!-- Data source beans will be initialized from external properties file. -->
<bean id="dsPostgreSQL_Daifcqkp30zkdj" class="org.postgresql.ds.PGPoolingDataSource">
<property name="url" value="#{systemEnvironment['dsPostgreSQL_Daifcqkp30zkdj_jdbc_url']}"/>
<property name="user" value="#{systemEnvironment['dsPostgreSQL_Daifcqkp30zkdj_jdbc_username']}"/>
<property name="password" value="#{systemEnvironment['dsPostgreSQL_Daifcqkp30zkdj_jdbc_password']}"/>
</bean>
Then, just set your environment variables:
IGNITE_VERSION=2.7.5
CONFIG_URI=https://raw.github.com/some/path/to/your/config.xml
OPTION_LIBS=ignite-zookeeper,ignite-rest-http
EXTERNAL_LIBS=https://github.com/some/path/to/your/jdbc-drivers/postgresql-42.2.6.jar?raw=true
dsPostgreSQL_Daifcqkp30zkdj_jdbc_username=0a9suf09asdfkjwel
dsPostgreSQL_Daifcqkp30zkdj_jdbc_password=8faskdfn94noiasnf09_s09fklajfealk
dsPostgreSQL_Daifcqkp30zkdj_jdbc_url=jdbc:postgresql://<host>:<port>/Daifcqkp30zkdj?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory

Had the same issue, probably didn't resolve it the "correct" way (whatever that is), but resolved it this way for a POC nonetheless:
Create a standalone jar file with only the secrets file
Give it the name dsPostgreSQL_Daifcqkp30zkdj_jdbc.jar or similar
Place the jar file in the libs directory
It seems the classpath is just the contents of all JAR files in the \libs subdir, so oblige it... This would have the advantage of allowing for a signed JAR - I believe - which would (in addition to file system permissions, visibility, etc.) at least ensure it isn't tampered with.

Related

WebSphere Liberty: Access properties file from library jar file

I am running on WebSphere Liberty 17.0.0.4. Deployed a web application and custom authentication module which is located under {wlp_install_dir}/lib directory. And that jar file is marked as library in server.xml file. Here is how it looks in server.xml
<library id="CustomLoginModuleLib">
<fileset dir="${wlp.lib.dir}" includes="custom_auth.jar"/>
</library>
Now the thing is, I want to use .properties file located inside custom_auth.jar file to the web application.
Have tried following code snippet to access:
this.getClass().getResourceAsStream("location/of/package/file.properties");
ClassLoader.getSystemResourceAsStream("location/of/package/file.properties");
But, neither works.
Any idea how can we access properties file located in library jar file.
Please see my response to this same question on dwAnswers at:
https://developer.ibm.com/answers/questions/444708/how-to-access-properties-file-located-in-library-j.html
To summarize the answer from there:
(1) I would never recommend putting user-provided JAR files in the {wlp_install_dir}/lib directory - that dir is only intended for IBM-provided JAR files. Instead, I would suggest putting your custom_auth.jar in your server directory or in a shared directory.
(2) You will need to associate the shared library with your application(s) like so:
<application location ="{appName}.war"> <!-- or {appName}.ear -->
<classloader commonLibraryRef="CustomLoginModuleLib" />
</application>
Depending on your needs, you can use a commonLibraryRef (as shown) or a privateLibraryRef. More info on shared libraries can be found here: https://www.ibm.com/support/knowledgecenter/SSD28V_9.0.0/com.ibm.websphere.wlp.core.doc/ae/cwlp_sharedlibrary.html
(3) As for loading the file in the Java code, your first line will work - assuming that this refers to an instance of a class in your application. I also assumes that the path you pass to the getResourceAsStream method is the same as the path to the file inside the library JAR.
Hope this helps, Andy

where spring defines variable value, which is referred by some xml file

I am trying to understand from where does the value of a variable comes from, when it is referred in Spring xml file.
For example:
<context:property-placeholder location="classpath:/${com.example.deploy.environment}/com.example.config/mysql.properties" ignore-resource-not-found="false" />
Where is the value of com.example.deploy.environment defined? In my project I searched all over, however i couldn't find anywhere where this values is defined.
Any information in understanding this would be of great help.
This value can come from a variety of source:
application.properties file which you can define in PropertyPlaceholderConfigurer bean.
<bean id="mailProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:application.properties" />
</bean>
...
//Inside application.properties
com.example.deploy.environment=prod
You can provide via command-line:
With Maven vm arguments for JVM System property:
mvn package -Dcom.example.deploy.environment=prod
Running Spring Boot Application:
java -jar app.jar --com.example.deploy.environment="prod"
From System Environment variable of the Operating System. You might have to restart after setting environment variable. See below for windows:
Refer this doc and this article for more info.

Spring how to load file path of a text file in spring property file

This might be an extremely simple question but I'm really new to spring framework and am just getting my feet wet. I am trying to specify a text file property as part of a bean, the value for which I am specifying from a properties file.
The relevant code is as follows in context.xml file
<bean id="myAssembler"
class="com.pkg.search.myclass.collector.assembler.myAssembler">
<property name="popularUrlsFileName" value="${POPULAR_URLS_FILE}"/>
</bean>
The POPULAR_URLS_FILE is specified in a .properties file as :
POPULAR_URLS_FILE="README.md"
But I am getting an error in the xml file as it says it can't find the file with README.md path. What exactly are we supposed to specify as far as the path is concerned for it to find the text file?
Exact error is "Cannot Resolve File README.md"
Any help would be much appreciated. Thanks in advance!
You have two options, if the file is on the classpath than
POPULAR_URLS_FILE="classpath:path/to/README.md"
or, if not on the classpath, use the file URL syntax
POPULAR_URLS_FILE="file:path/to/README.md"

Overriding a few properties for junit test using spring or camel property placeholder in a maven layout

I want to specify only the properties I want to override in a test properties file of the same name in the src/test/resources folder.
A little more detail...
In a maven layout I have a properties file that contains the deployed value to use (eg. input.uri).
src/main/resources/app.properties:
input.uri=jms:topic:in
app.name=foo_bar
This file's properties are loaded into the context.xml file by the property-placeholder:
src/main/resources/META-INF/spring/context.xml:
<context:property-placeholder properties-ref="springProperties"/>
<util:properties id="springProperties" local-override="true" location="classpath:app.properties" />
I have the test properties file with the same name, app.properties, in src/test/resources folder and override the input.uri definition to one that my junit test will use. (note, app.name doesn't change).
src/test/resources/app.properties:
input.uri=seda:in
How would you write the junit test and/or a test context.xml file so that properties are loaded from the src/main/resources/app.properties file, but any properties defined in the src/test/resources/app.properties file override the ones in the src/main/resources/app.properties file? Without it being obvious that you're loading two different files either in the src/main files or src/test junit test files - I want the property placeholder to search the classpath and pick the right values.
You will have to provide a different name though - if both the properties in the main and the test have the same name, the entire properties in one or the other will take effect.
Instead an approach like this has worked for me:
In your src/main/resources/META-INF/spring/context.xml do this:
<context:property-placeholder location="classpath:app.properties" local-override="true" properties-ref="springProperties"/>
<util:properties id="springProperties">
</util:properties>
In a test-context.xml file:
<import resource="classpath:/META-INF/spring/context.xml">
<util:properties id="springProperties"> <!-- or refer to a overriding file -->
<prop key="input.uri">seda.in</prop>
</util:properties>
This will override the properties for you, while maintaining the not overridden values from the original file.

Can I default a system property for a constructor-arg in a spring config file?

I have a spring config file which includes the following elements:
<context:property-placeholder location="classpath:default.properties"/>
<bean id="theVar" class="java.lang.String">
<constructor-arg value="${varName}"/>
</bean>
"varName" is now moved from the properties file to a system property. It is being added when I start a Maven build:
mvn clean install -DvarName=data
I want to also run my build without specifying varName:
mvn clean install
Is there some way to default varName in my spring config? Though this does not work, a conceptual example of what I am looking for is:
<bean id="theVar" class="java.lang.String">
<constructor-arg value="${varName}" default="theDefaultValue"/>
</bean>
Spring 3.0.x supports a syntax like this:
value="${varName:defaultValue}"
References:
SPR-4785
Changes in version 3.0.0.RC1 (2009-09-25) (PropertyPlaceholderConfigurer supports "${myKey:myDefaultValue}" defaulting syntax)
It turns out that in spring v2.5+, if there is a system property defined, it can be used instead of a property defined in the properties file. You just need to ensure the same name is used and that the 'override' option is enabled.
For example, given:
<!-- my spring config file -->
<context:property-placeholder location="classpath:default.properties" system-properties-mode="OVERRIDE"/>
And:
# default.properties file
theVariable=One
When I execute:
mvn clean install
"One" is picked-up for theVariable. If I execute:
mvn clean install -DtheVariable=Two
"Two" is picked-up instead.
I'm not sure If this will help but if you are annotating classes and want a default value when a system property is not present this is what I currently do:
#Value("#{systemProperties['fee.cc']?:'0.0225'}")
public void setCcFeePercentage(BigDecimal ccFeePercentage) {
this.setCcFeePercentage(ccFeePercentage);
}
It can be done as #sebastien has described but in the configuration file as you want:
<bean id="theVar" class="java.lang.String">
<constructor-arg value="#{systemProperties['varName'] == null ? 'default_value' : systemProperties['varName']}"/>
</bean>
If your varName variable is not present, default value will be set.

Resources