What are the best practice recommendations for configuring a Java EE 7 configuration file?

Where does the application configuration relate to modern Java EE applications? What best practice recommendations do people have?

By application configuration, I mean settings, such as settings for connecting to services in other mailboxes, including external ones (for example, Twitter and our internal Cassandra servers ... for things like hostnames, credentials, retries), and also those related to business logic (things that can be tempted to be stored as constants in classes, for example, days for expiration, etc.).

Assumptions:

  • We deploy a Java EE 7 server (Wildfly 8.1) using one EAR file that contains several wars and one ejb-jar.
  • We will be deploying in various environments: unit testing, on-premises developer installations, cloud infrastructure for UAT, stress testing and production environments. Many of our properties will vary in each of these environments.
  • We do not mind linking the configuration of properties to the DI framework if this is the recommended recommendation.
  • All this is for a new development, so we do not need to comply with obsolete requirements or restrictions. We are very focused on modern modern methods.

Is the configuration inside or outside the EAR?

If outside the EAR, where and how best to securely access them?

If inside an EAR we can store it anywhere in the class path to facilitate access at runtime. But with every configuration change, we would have to reassemble (and possibly rebuild). And since we will have several environments, we will need tools to differentiate files in the EAR. Here I see two options:

  • Use the expected file names (for example, cassandra.properties ), and then create some environment appxyz-PROD.ear (for example, appxyz-PROD.ear ).
  • Create one EAR (for example, appxyz.ear ) and put all of our various environment configuration files in it, adding an environment variable to each configuration file name (for example, cassandra-PROD.properties ). And, of course, adding an environment variable (in vm or otherwise) so that the code knows which file will be downloaded.

What are the recommendations that people can recommend to solve this common problem?

Thanks.

+5
source share
2 answers

I do not know what is best, but here is what we do.

(Note that this only works for one installation for each application on the server and will fail if you want to use multiple deployments to the server, say, for deployments with multiple applications).

Entering CDI Values

We use a somewhat sophisticated approach to CDI injection to enter configuration values ​​from .properties directly into beans, for example:

 @Inject @ConfigurationValue(value="amazonS3FileContentsAccessKey") private String accessKey; 

The corresponding @Producer bean reads configuration files from the class path and from the specified "local" location:

global / local .properties files

  • Each EAR contains a “global” .properties file in the class path for configuration values ​​that rarely change and / or usually remain consistent across environments (for example, days for expiration). In addition, the global configuration file contains normal default values ​​(for example, " localhost " for the database server name). Global properties files (there are several of them, see below) are supported in the source tree.
  • For each development / installation / server / deployment environment (possibly) this is a “local” properties file containing local parameters that overwrite global configuration parameters, such as database names, passwords, etc.

The expected path to the "local" property files is configured in the global configuration file (for example, /etc/myapp/local.properties ) or C:\myapp\local.properties .

In fact, we even allow the replacement of some variables in the file name for local configuration files, such as " ${hostname} ". The initial idea was that local properties could also be maintained in some central source control by distinguishing them by host name ( local.machineA.properties , local.machineB.properties ), but we are not using it at the moment, because that our production settings are the same on all machines (Amazon S3 keys, database password / host, etc.).

Assembly for developers, testing, production

We collect different EARs depending on the development stage using Maven profiles.
Optionally, the desired global.${profile.name}.properties file (where profile.name is, for example, dev or production ) is copied to the expected global.properties file in the class path.

For example, dev and testing share a common secret / bucket AmazonS3, which is configured once for all developers in the configuration.dev.properties file, and configuration.production.properties does not contain our production keys.

In addition, in our dev and testing environments, there is debugging enabled and configured, such as web.xml , but of course, staging and production do not. Our .properties approach cannot modify files like web.xml , but easily create Maven profiles.

+3
source

Depending on each experience, there may be many possible solutions to your question. So why not try some of the ideas already discussed. Take a look

We hope that these two will give you a common understanding of how you can build your entire environment using maven.

0
source

Source: https://habr.com/ru/post/1203976/


All Articles