Simeon Leyzerzon
Simeon Leyzerzon

Reputation: 19074

Environment-specific externalizing properties file(s) in Spring Boot

I have a Spring Boot app that runs as a jar via the following script (excerpted):

SERVICE_NAME=submit-enrollment
PID_PATH_NAME=~/submit-enrollment/application.pid
PATH_TO_JAR=~/submit-enrollment/submit-enrollment-1.0.0.jar
JVM_OPTS="-Xmx1g"
SPRING_OPTS="--logging.file=submit-enrollment-1.0.0.log"

case $1 in
    start)
        echo "Starting $SERVICE_NAME ..."
        if [ ! -f $PID_PATH_NAME ]; then
            nohup java $JVM_OPTS -jar $PATH_TO_JAR /tmp 2>> /dev/null >> /dev/null $SPRING_OPTS &
                        echo $! > $PID_PATH_NAME
            echo "$SERVICE_NAME started ..."
        else
            echo "$SERVICE_NAME is already running ..."
        fi
    ;; .........

Configuration property files (2 for now: application.properties and submit-enrollment.properties) reside inside the above jar file in the app root and the property values from them are read into various beans via @PropertySource and @Value annotations, for example:

submit-enrollment.properties:

marshaller.contextPaths=c.f.e.a_e.e_1, c.f.e.a._1
default.Uri=https://i.h.c.com/I1/AEService  
soap.action=http://wsdl.business.services.ee.ffe.c.h.com/AEPT/CAMIPR
auditLog.server=10.172.x.xx
auditLog.port=8062

application.properties:

spring.main.show-banner=false
server.port=9278
logging.level.org.springframework.ws.client.core = DEBUG
logging.level.com.sun.xml.internal.messaging = DEBUG
#logging.level.org.springframework.ws.client.MessageTracing = TRACE
#logging.level.org.springframework.ws.client.MessageTracing.received = TRACE

=================================

@Configuration
@ComponentScan({"c.f.e", "c.z.submit.enrollment"})
@PropertySource("classpath:/submit-enrollment.properties")
public class SubmitEnrollmentConfig {

    @Value("${marshaller.contextPaths}")
    private String[] marshallerContextPaths;

    @Value("${default.Uri}")
    private String defaultUri;

==================================

@Service("soapClient")
public class FmfSoapClient extends WebServiceGatewaySupport {

@Value("${soap.action}")
private String soapAction;


@Value("${auditLog.server}")
private String auditLogServer;

@Value("${auditLog.port}")
private String auditLogPort;    

As application grows, other .properties files will be added, probably something along the lines of used spring components, i.e. security.properties, web-services.properties, web-properties, etc. vs a single submit-enrollment.properties file.

That's the current setup. What I'm looking for is the following:

Question:

I'd like to be able to have the .properties files become externalized to reside somewhere on the file system outside of the jar file as well as have them named in a manner reflecting the environment:

application-dev.properties
submit-enrollment-dev.properties

;;;;

application-uat.properties
submit-enrollment-uat.properties

;;;

application-prod.properties
submit-enrollment-prod.properties

I'd like to pass Spring Boot a parameter in the shell script telling which environment I'm running it in:

java -jar submit-enrollment.jar -environment=uat

and have Spring automatically resolve the proper properties files based on their -env- value that would correspond to the parameter above. Is that something that currently exists as part of Spring Boot functionality, if so could someone please point me to some sample setup like that. If that is, in your opinion, not a viable approach, perhaps instead of having .properties files with different name resolved by Spring it would be better to segregate them into an environment specific directory while letting them have the same name across the environments, should I resort to doing it in Maven or Jenkins instead of having Spring Boot do it at run time? Are there better solutions?

Upvotes: 1

Views: 2735

Answers (1)

Stephane Nicoll
Stephane Nicoll

Reputation: 33091

The problem is that you want to change both the name of the file and have Spring Boot pick up automatically the environment that you have specified.

Spring Boot supports profile specific properties out-of-the-box. So if you enable the uat profile, it will look up for a application-uat.properties in the usual locations.

If you don't like application as a prefix, you can specify the SPRING_CONFIG_NAME system/os property to define a different name.

If that does not work for you, you can use SPRING_CONFIG_LOCATION to tell Spring Boot where to look for things. You can then list either directories or individual files. That last property gives you maximum flexibility and should probably meet your requirements but it's more work on your end.

Upvotes: 1

Related Questions