Best way to use configuration file in production - java

I'm currently working on a java project.
I already built the JAR for the project, and this JAR uses some properties files that have credentials for third party services in them.
So this program reads the configuration files from "src/main/resources". But I don't think this is the best way to bring it to production since the properties files have credentials.
My question is, what is the state of the art to deploy a JAR to production server that reads properties files that have credentials in them?
Do I just put the properties files in "src/main/resources" like I did and it's enough? Is it safe enough?
Or should I not actually push the properties files with credentials in production and there is a better way to do that?
directory

You can manage many configurations on spring-boot for each enviromment ( local, prd, hom, test... )
check this https://stackoverflow.com/a/68012400/7505687
Or you can work on each vars in .proporties overriding all values as your PRD enviromment vars are added.
eg. in application.properties
var.same-config-on-proporties=${ENV_VALUE_FROM_ENVIROMMENT:default-value-if-not-passed-from-env}

Related

Gradle exclude property value or file from gradle during build except locally

So i am not really sure how to ask this question so I am going to try my best.
I currently have a file within my project that is used for SSO oidc configuration. For the most part we do not use it, most of the configuration comes from the dev database. The only value that we do use is the callback url, Which calls back to localhost instead of the dev environment. When my application starts up i check to see if that file exists and pretty much override dev configurations with anything in that file. Mostly so we can just return back to localhost. I also do development work and need to add or change additional values locally so the ability to override is needed for me specifically. So the issue i am trying to find a solution for is when we jar the application that oidc configuration file also gets included and deployed to the server. This then will make the dev environment point to localhost. I tried excluding that oidc configuration file from gradle but then when i run the application locally it also excludes it and then does not have the file locally. I am trying to figure out a way to only exclude that oidc file configuration when deployed to dev/test/prod but keep it locally. Or maybe even a different approach would work too.
For this case, you can create a local directory in your resources folder, then in gradle you can exclude this directory specifically to be bundled when jar is created using below:
jar {
exclude ("DIRECTORY-TO-EXCLUDE/**")
}

Copy properties to modules in multi-module project

I need to put my own properties (many different) to many modules. The properties contain sensitive data (DB passwords for example), so I cannot put it to my git repository. For now, I have 2 Jenkins jobs:
First clones my "project" and builds it.
The second clones my other repository that contains only properties and some .sh files. Then I copy properties from the second project and paste it into my .jar file.
The problem is that I have to "unzip" (or "unjar"?) the jar file, then paste properties, and after that "jar" the file again. Not so clear.
Good thing about that is if I want to change my properties I don't have to rebuild all project. Just run the second job and that is all.
I found some other options:
Jasypt
So I can encrypt my properties. Then I can store it in my repository. Not bad, but I do not see what password is stored. Next question - when I want to change something in my properties I need to build all over again. So Jasypt is a good idea to make your sensitive data safer but did not resolve my problem.
maven-remote-resources-plugin
I don`t know it at all, but maybe it is a better way to paste my properties into my project?
Maybe There are other ways to do that? Or maybe now I am doing it how it should looks? Btw. I am using spring boot 2.0.3.

How to use different sets of property files on a build server and on developers' machines?

I have a web application. I'm configuring CI for it.
We didn't use a build tool (neither Ant nor Maven), and made builds by means of IDE.
Now I'm working on an Ant script which will be used by our build system.
There are several property files which should have different properties' values when the project is build on the build server but not on local machines.
What are the common approaches for handling such situation?
If we used Maven, I would probably go with using different profiles, but we have Ant.
One possible solution which I can see is creating a root folder for all property files sets, and storing each set in a separate subfolder (see the schema below).
/profiles
/dev1
prop1.properties
prop2.properties
/dev2
prop1.properties
prop2.properties
/build-server
prop1.properties
prop2.properties
/webapp
/WEB-INF
Then during the Ant build we can copy the correct set to the correct location. But it can be a problem to make builds by IDE as we used to do (because property files are not stored in their proper place under src folder any more).
Are there any other approaches?
If I understand you, you build separate ear/war/jars for each and every environment on your continuous build server. Is that correct?
I have two ways I handle this: The Smart Way, and the Dumb Way:
Smart Way
The smart way is to configure your application server (JBoss, Weblogic, etc.) to look for the desired property file external to the jar/ear/wars that are installed in the application server. This way, you build one set of jar/ear/wars, and it works everywhere. Plus, you do something very, very important: You cause the Finger O' Blame to point elsewhere.
If the properties files are packaged as part of the jar/ear/war, and something on the server changed, you'd get the blame because the your build was bad. Sure, you had no way of knowing the they changed the environment, but you did install that bad build file on the production server.
However, if the properties are stored outside of the build artifact, then it's the team responsible for configuring the servers that's at fault.
Actually, it's a lot easier for the team responsible for configuring the application server to handle the issue. They know what got changed, and they can update the properties file to reflect that change. Not only that, but you're only having to build and distribute a single set of artifacts. You don't have to worry if a new environment is setup, of if something in the old environment changes. In fact, changes can easily take place without forcing you to do a new release.
Dumb Way
We were able to do things the Smart Way at my last company. At my current company, we do things the Dumb Way. The properties are embedded in our build artifact, and there is no easy way to change it.
I divided each set of properties files by suffix instead of different directories (i.e build.properties.dev1, build.properties.dev2, etc). We placed properties files were put in a single directory.
When I do a build, I use the AntContrib <for> task to loop through the build process multiple times, each time with a different properties file. I then build an artifact for each and every set of properties files. I use the suffix on the properties file as folder names in my target directory where I store the built artifacts. That way, each build produces all the artifacts for all the environment.
That way, if the artifact worked in the dev environment, it will work in QA and Production. The only problem is that I'm storing 5 to 10 times the number of artifacts on my Jenkins server, so I need 5 to 10 times the disk space.
By the way, as long as I can define a <fileset> to find the properties files, I can use the <for> task, so you can use the different directories. And, you can use <basename> to pluck off the directory names.

log4j is not working in weblogic server?

I am using weblogic 10.3.4, I am trying to write log with log4j. but at runtime my application is not getting any log4j.properties. even this is not generating any warning as "initialization of log4j has error".
I have tried my properties file to put in src folder, classes folder and then I created one jar and put it in domain lib. still its not picking. even when I am writing log with same jar in standalone application, its working fine.
please help me with valuable suggestions.
I tried the solution proposed at Oracle forums.
Excerpt from that link at Oracle forums:
I've only modified the scritp startWebLogic.cmd:
set LOG4J_CONFIG_FILE=log4j.xml
set SAVE_JAVA_OPTIONS=%JAVA_OPTIONS% -Dlog4j.configuration=%LOG4J_CONFIG_FILE%
#REM set SAVE_CLASSPATH=%CLASSPATH%
set SAVE_CLASSPATH=%CLASSPATH%;C:\Oracle\Middleware\user_projects\domains\domain\config
In this way I've put all the config folder inside the classpath, and I can use it in future to hold other libraries configuration files (for example oracle coherence config).
I tried this approach on a different properties file as well and that worked well!
You need to either specify where the application should find its log4j.properties, or put it onto the classpath of the application. Where the classpath is varies, but in general WEB-INF/classes should work. Other options depend upon how you're deploying the application.
A better long term strategy is to configure your system so that you can change the log4j.properties depending upon the environment. When you're in production, you won't want all of the debug information to appear. Look at the answer to this question or this question for more ideas. One strategy is to define a variable on the command line which gets picked up and defines a directory which contains your configuration files. This works for Tomcat, but there may be other, better, strategies for Weblogic.
It is not a good idea to change the configuration of your server, in particular, don't replace the log4j.jar or log4j.properties in your server directories. The server will depend upon the version that it was designed to use, which may or may not be the same as your version. You can do everything you need to do by changing the war that you're deploying.
I have used this code:
ClassLoader cl = this.getClass().getClassLoader();
URL log4jCfg = cl.getResource(configFile);
if (log4jCfg != null) {
DOMConfigurator.configure(log4jCfg);
}
log.info("log4j is now working on Web App.");
In my case, we used XML configuration:
log4jCfg = "mylog4j.xml";
In WebLogic, we were able to place such file (mylog4j.xml), equivalent to your log4j.properties file, at WebLogic's domain path (specific to the domain were we deploy). This means that domain folder belongs to your application's path. I just tested it with Web applications, I'm not sure if with SOA or EJB projects it works the same way.
When you deploy any application on any server that application should use servers log4j jar.
So if you have added any log4j jar in your application jar/tar/ear, remove it and copy log4j.properties file in the conf folder of the server from where server is picking its configuration files. Or just copy your log4j property content in servers log4j property file.

different configuration files for different server

Hi How would you solved that?
I have one application in which I have a few configuration files, I make war file and deploy it on the tomcat.
But at the same time I have to make the war file and deploy the same application under different context and/or a server with modified configuration files.
I can create my own task in ant, and replace needed paramaters but there can be possibility of moving to maven, and anyway I'm not sure about it. Or can I use something like spring's property place holder configurer or jgroups
Spring can handle this quite well in a variety of ways. The approach I found most useful and flexible is to setup in each environment a system variable that specifies trhe environment name e.g. test, dev, int, prod, etc.
Spring can then use this system variable to load the correct property files. Depending on your needs these property files can be bundled with the app or loaded from an external location. Theres an example of a similar approach here:
http://www.developer.com/java/ent/print.php/3811931
I'd deploy Spring apps packaged as a WAR to either Tomcat or WebLogic without any changes. It would contain both the META-INF/context.xml for Tomcat and weblogic.xml for WebLogic. No worries, no changes.
What we did was create a folder structure for the properties that were environment specific. Under that folder we created folders for each specific environment targeted for deployment, including local development. It looked like this:
Project
\
-Properties
\
-Local (your PC)
-Dev (shared dev server)
-Test (pre-production)
-Prod (Production)
In each folder we put parallel copies of the properties/config files and put the different configurations only in the file in the appropriate folder. The secret was to control the classpath of the deployment environment. We defined a PROPERTIES classpath entry on every server. On Prod, it would be set to "$ProjectDir/Properties/Prod" while on Test the same variable would be set to "$ProjectDir/Properties/Test".
This way we could have database connection strings for the dev/test/prod database preconfigured and not have to checkout/in the property file each time we wanted to build for a different environment.
This also meant that we could deploy the exact same .war/.ear file to Test and Prod without rebuilding. Any properties that weren't declared in the properties file we handled in a similar way by using the same JNDI name in each environment but using values that were specific to that environment.
http://www.gifnoc.com/config could help as it stores configuration on a central place and the client is pulling from it for different environments

Categories

Resources