Configuring hystrix command properties using external properties file - java

in my project in which I used the Hystrix as a library and for Command properties I declared it in another external properties file as follows in the config.properties file:
hystrix.command.ExampleImpl.execution.isolation.thread.timeoutInMilliseconds = $ {project.endpoint.example.timeout}, knowing that project.endpoint.example.timeout is set in the external properties file, whereas before this file was in the build with the config.properties file and it went well
and so now I have a default isolation.thread.timeoutInMilliseconds value of 1000 ms.
someone has an idea about this problem.

Related

Read external .properties file from the install directory (not the current directory)

I am distributing a Spring Boot application as a zipped "bootJar" using the Gradle Application plugin and the "distZip" task. The end-user will get the zip file, unzip it, and run it by just typing "myApp" (a shell script nicely created by the plugin).
I would like the end-user to create a "myapp.properties" file (a name I chose) and put it in the installation directory, or a "config" directory under the installation directory.
Suppose I set up my embedded (in the jar) application.properties file as follows:
spring.config.import = file:./myapp.properties will only read from the current directory
spring.config.import = file:/etc/myapp.properties will read from the specified directory -- but I don't know what this is at build time (the end-user determines it at installation time)
How can I set up my application so that Spring Boot can read properties from an external file whose location is specified later?
NOTE: I know I can play around with the generated scripts to pass in environment variables or Spring Boot properties, but I was hoping to do this completely within Spring Boot so I don't need to modify the nicely generated shell scripts.
spring.config.import = file:./myapp.properties will only read from the
current directory spring.config.import = file:/etc/myapp.properties
will read from the specified directory -- but I don't know what this
is at build time (the end-user determines it at installation time)
Why overcomplicate this.
Place inside the jar all the properties that you want to be statically configured as default values when you build the application.
Embedded application.properties
server.port = 8080
prop1.element = something
Then the client can create another file application.properties and place it in the same directory with the jar and define more properties which are not already defined.
prop2.element = something2
prop3.element = something3
By default Spring Boot will load properties both from the embedded file as well from the file in the current directory where the jar is placed during startup.
In the external application.properties you can also overwrite properties existing in the embedded application.properties. So if the external file in the current directory same as the jar is the following
prop2.element = something2
prop3.element = something3
prop1.element = something4 <--- this value here will overwrite the value 'something' from embedded file
According to spring doc
SpringApplication will load properties from application.properties
files in the following locations and add them to the Spring
Environment:
/config subdirectory of the current directory.
The current directory
classpath /config package
The classpath root The list is ordered by
Precedence (properties defined in locations higher in the list
override those defined in lower locations).
After having more input from the comments, it seems that you face another issue as well. You start the application from command line from another directory so that is counted as the directory where spring will look for the external configuration instead of where the jar is placed.
So for example let's say that the jar is placed inside the target folder that exists in current directory. You start the application using the following command:
java -jar target/demo-0.0.1-SNAPSHOT.jar
But then the external application.properties existing inside target folder is not loaded from spring because you executed the command from another directory. This can be solved if you start the application in the following way
java -jar -Dspring.config.additional-location=./target/ target/demo-0.0.1-SNAPSHOT.jar
This should not be difficult as you already provide the path where the jar exists in the command line.

Spring not looking in the Config subfolder

I am new to Springboot and I am having trouble with externalizing my properties files.
I have multiple ".properties" files that I have kept in a subdirectory "config/". I have removed context-placeholders from my project and have included the comma-separated properties files while executing the jar.
eg. java -jar myjar.jar --spring.config.location=file:////config/PROP1.properties, file:///config/PROP2.properties -debug
I have few questions
Why are the files in the config directory not being read even after explicitly mentioning where to look?
I have my own dependencies in the project that have same-named properties files packed in its jar. Is that creating any sort of problem when SpringBoot tries to read the files from the config folder while executing my project jar?
Update
Now I am keeping only a single properties file suppose ABC.properties outside the jar in the same directory . I am using the name "ABC" instead of "application". I am using the below command
java -Dserver.log.dir=/path/to/log/dir -jar myjar.jar --server.port=9090 --spring.config.name=ABC --prop1=val1
I have overriden a property in my external property file but I don't see the overriden value being used when I run the application. My new questions are
Is there anything wrong with the command-line?
I have the following line in xml bean configuration
<context:property-placeholder location="ABC.properties" />. Is this causing any sort of problems to detect and use the external properties?
If the above is true and I have to remove the line how will SpringBoot understand from where the property values are to be imported?
(Not related directly to the question) Is there a order that I need to follow while giving command line arguments?
Spring boot has explicit indicate how to write this external configuration. See doc ref here: https://docs.spring.io/spring-boot/docs/2.5.2/reference/htmlsingle/#features.external-config.files
Basically, you need to specify the location like this:
--spring.config.location=classpath:/somefolder/somefile.properties
--spring.config.location=file:./somefolder/somefile.properties
From your command line, it seems that you are missing one dash, and also using a wrong format of file schema.
Q1: Why are the files in the config directory not being read even after explicitly mentioning where to look?
A1: If your config folder is beside your jar file, your command should be like
java -jar myjar.jar --spring.config.location=file:./config/PROP1.properties
meanwhile, you can also use the full path to target your config file.
Q2: If I don't mention the properties files names explicitly as an argument then they won't be picked up even when they are in the config directory
A2: No. See this doc, Spring Boot will try to find config files from the four places:
A /config subdir of the current directory.
The current directory
A classpath /config package
The classpath root
If spring.config.location is not set, files in these folders named application.properties will be treated as valid config file. You can change the accepted file name by setting property spring.config.name.
Q3 About Config File Priority
A3 As described in the doc mentioned earlier, if same name properties appear in different config files, locations higher in the list override lower items.
Another tip, it will be better to remove config files inside the jar file, so you can get a full view of configuration just in one place (the externalized config folder);

Does bnd launcher support configuration files that are made known with system properties?

When I launch an application from bndtools (using a file launch.bndrun), I can specify -runproperties: java.util.logging.config.file=jul-debug.properties, with jul-debug.properties being a file in the working directory. Everything is fine and works as expected, i.e. the java.util.logging properties are read from my configuration file.
When I create an export (launch.jar) using this lauch.bndrun, the configuration file jul-debug.properties is not included in the launch.jar. Can I add some instruction to launch.bndrun that causes the jul-debug.properties to be included in laucn.jar in such a way that jar -jar launch.jar will cause the configuration file to be evaluated?
I looked through all the -run... instructions for bnd, but couldn't find anything.

Maven Dependencies that read property files

I have a java project named dbstuff which reads properties from db.properties with getClass().getResourceAsStream("/db.properties"). The values are things like connection strings, etc. This dbstuff is used in various projects most of them are web.
I now have a dropwizard project (maven) which uses dbstuff.jar as a dependency, this project is compiled as a fat jar as described here, at the moment the dbstuff only read values from db.properties if the file is present in /src/main/resources, and when the package is created the db.properties becomes embedded in the jar.
What i want to achieve is to make db.properties external, so that i can have various db.properties (one for each environment) but only one dropwizard jar, is this possible?
thank you
You could pass in the path to the external db.properties file at runtime via a system property, e.g.:
java -jar myjar.jar -DdbConfig=/path/to/db.properties
Then in your code within dbstuff.jar you can load the properties file:
final String path = System.getProperty("dbConfig");
final Properties properties = Properties.load(new FileInputStream(path));
Alternatively, as you've mentioned you are using Dropwizard, within your configuration file (the yaml file or whatever you are using) have a property which specifies where the external db.properties file is, load the properties during server initialisation and then pass them on to whatever requires it in dbstuff.jar.
You could then take this a step further, forget about the db.properties file and have an entire section in your Dropwizard config that specifies all the properties, e.g.:
db:
url: jdbc://....
user: dbuser
# etc...
And then pass on what the objects in the dbstuff.jar need. See Dropwizard's configuration documentation for more information on how to do this.
I think you can create a configuration class in DropWizard and then use it to return the correct configuration for each environment - https://dropwizard.readthedocs.org/en/latest/manual/hibernate.html.
As for your question, if you have multiple resources on the same path, even if on different jars, there is no guarantee of which one Java will be using. When you add a file named db.properties to /src/main/resources, it becomes the resource "db.properties", and is read as such:
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResourceAsStream(java.lang.String)

Read system properties from file specified as java executable argument

By launching java with the -D option you can set System.properties.
Is there a way to specify a properties file as an option for java, which in turn read them as System.properties?
E.g.
java -Dfile ./alotof.properties
I'm building a webapp deployed in JBoss. The jboss xml configuration files accepts system properties as inline config {my.property}, which reads from the command line argument but this gets unruly as the number of properties grow.
You can read the properties file in bash (in run.sh file), parse properties and create the proper config line for JVM.
Here you can find 2 articles that can help you:
Reading Java-style Properties Files with Shell (permalink)
Reading java.properties file from bash
I don't know about giving a direct property file as an argument, but instead you can have startup class which loads at the bootstrap and overrides whatever property you want override from your property file using System.setProperty() method.
Java can't read system properties from a file, but JBoss can - use the SystemPropertiesService, configured through properties-service.xml in the deploy directory.

Categories