Micronaut + Maven - Environment variables - java

I am working on a Micronaut + Maven project.
I need to parametrize some values of my application.yml such as passwords and connection strings, to avoid committing them.
I know values can be parametrized this way:
secret-value: '${SECRET_VALUE}'
But i cant find any other way to set SECRET_VALUE except setting bash value in .bashrc or .profile or .envoirment script files.
I would like to use a .env file somehow, in order to commit a .env.example file in git repo.
Any thoughts?

According to maven-resource-plugin documentation :
https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
You could add a filter file in the filters tag of your pom file.
See we can separate "your.name" from the POM by specifying a filter file my-filter-values.properties containing: in the documentation above.

I may have lost the focus of the question.
the solution was simply create a .env file with required values, then run application using something like
dotenv run ./mvnw mn:run.
regarding #yunandtidus solution:
That is good only for "fixed" variables, such as application name, as pom values are shared between environments (assuming that we have an application-dev.yml and an application-prod.yml).
Keep in mind that, unlike .env, pom.xml must be committed, as any application.yml you have.

Related

Adding environment variables to Spring's application.properties

I want to run two Amazon S3's SDK information from the application.properties, but instead of putting it in the file, I want to add them when running ./mvnw spring-boot:run. I saw something like this could be done:
./mvnw spring-boot:run -Dspring-boot.run.arguments="--srp.storage.s3.access-key=FOOBARFOOBAR,--srp.storage.s3.secret-key=foobarfoobarfoobarfoobarfoobar"
I tried running the command above with quotes around the arguments and with/without whitespace between them. Also, I tried leaving blank values in the properties files as well as removing them at all.
# srp.storage.s3.access-key=
# srp.storage.s3.secret-key=
srp.storage.s3.access-key=
srp.storage.s3.secret-key=
I have a class annotated with #ConfigurationProperties("srp.storage"). The results of these attempts varied from application failing to start because no property was found by the class, to actually running but taking no effect. The variations of the command that caused the server not to start was not specifying any property in application.properties and attempting to run the command with and without quotes and no whitespace. The scenario that it ran but did not take effect was putting whitespace.
I know about running it using the built JAR file, but I want to be able, if possible, to run it like that just to prevent building every time I change something.
Also attempted to specify placeholder as shown here, but again no success. Can I even do what I want using ./mvnw? Or must it be with a JAR file?
srp.storage.s3.access-key=${access-key}
srp.storage.s3.secret-key=${secret-key}
./mvnw spring-boot:run -Dspring-boot.run.arguments="--access-key=FOOBARFOOBAR,--secret-key=foobarfoobarfoobarfoobarfoobar"
Solved using environment variables. That's good enough for me.
It goes without saying you can choose any name you want for the property in Spring's file and variable, just remember that in Linux environments you must set the variable names all capital letters and use underscore.
In .bashrc or .zshrc or similar, add:
export AWS_S3_ACCESS_KEY=FOOBARFOOBAR
export AWS_S3_SECRET_KEY=foobarfoobarfoobarfoobarfoobar
And as shown before, in the application.properties file, add;
srp.storage.s3.access-key=${AWS_S3_ACCESS_KEY}
srp.storage.s3.secret-key=${AWS_S3_SECRET_KEY}
And start normally. Much better.
If you are using gradle and have bootRun task available then you can configure the task to read the args passed while running the task.
Add the following to your build file.
bootRun {
if (project.hasProperty('params')) {
args project.params.split(",")
}
}
Then you can run the following command.
.\gradlew.bat bootRun -Pparams=--demo.prop=commandlinearg
I had a field annotated as the following
#Value("${demo.prop}")
private String prop;

Micronaut PropertySource for multiple configuration files

I have a micronaut project where I want to have an unnversioned configuration file for private data (like database connections and so on)
This information have to be loaded through #Property annotation, but since there will be more than one .yml (there will also be at least an application.yml) y want to be able to provide file's path to #Properties to be able to differentiate where to look for property.
Since it's my first micronaut project I'm a bit lost with this stuff but taking springboot as an example, what I want to do is something like:
#PropertySource("classpath:configprops.properties")
But after reading micronaut documentation(https://docs.micronaut.io/latest/guide/index.html#configurationProperties) I found myself unable to do this (except from something like just reading the plain file which I guess would not be micronaut compliant)
I do it by passing jvm arguments.
For example, If I am running it on my local machine using gradle:run, I add following to build.grade
run.jvmArgs('-Dmicronaut.environments=dev', "-Dmicronaut.config.files=${System.getProperty("user.home")}/auth-config.groovy")
For my jar deployment, I have made a deploy.sh file as follows :
#!/bin/bash
fuser -k 8181/tcp
nohup java -Xmx512m -Dmicronaut.environments=staging -Dmicronaut.config.files=<path-to-config>/config.groovy -jar application-0.1-all.jar > application.log 2>&1 &
Also note that I am passing different environment names, this helps you to include development environment config directly in code if you want.
Like
application-[environment_name].groovy
application-[environment_name].yml
application-[environment_name].properties
This will help new contributors on your project to speedup the process project setup, I generally also include note in my application-dev.groovy file
DEVELOPER NOTE:
***** DO NOT COMMIT ANY CHANGE IN THIS FILE IF YOU MAKE ANY
*******************************************************
***** CREATE <config.groovy> file in your <HOME> folder and copy paste content of this file
***** Override properties as required
*******************************************************

How to load data from properties file in Maven?

I have migrated to Maven project (using Spring) where I don't need to use my old *.xml config files.
The adaptation was easy but what I still can't figure out is: how to let know to my project that I have properties file and wanna use it?
(If you know how to register properties file in POM, please add some brief description how to load data from this file. (if there is any significant difference in using )
EDIT:
In old project, I had just spring-mvc-dmo-servlet.xml config file, where I put every configs (like "scan all components in my projects, cus I don't wanna declare them explicitly"...
If I wanted to let my spring project know I have special file (In this case countries.properties with content what I wanna use - I had to put following code into the config file -
<util:properties id="countryOptions" location="classpath:../countries.properties" />
... only after that, i could wire the content from the file with fields in my classes...
like this
#Value("#{countryOptions}")
private Map<String, String> countryOptions;
(but now I don't have any spring-mvc-dmo-servlet.xml anymore, now I have only POM.xml and in POM my old expression doesnt work ofc )
So my question is:
What I have to put into my POM to say my spring project "HEY THERE IS SPECIAL FILE !"
And how to wire it (#{countryOptions} or ${countryOptions} or something else)
You need to use a maven plugin to load the properties from file
One of them is
http://www.mojohaus.org/properties-maven-plugin/usage.html
EDIT:
In one of our spring boot projects, the path to a property file is passed trough command line using the option:
--spring.config.location=$DIRECTORY/application.properties
Then to get the values:
/** The property to get. */
#Value("${property.to.get}")
private String propertyToGet;
You can also take a look at #PropertySource annotation
#PropertySource("classpath:config.properties")
See https://www.mkyong.com/spring/spring-propertysources-example/

Spring boot external properties file in "current directory" is ignored

from the manual:
24.3 Application property files SpringApplication will load properties from application.properties files in the following locations and add
them to the Spring Environment:
A /config subdirectory of the current directory.
The current directory
A classpath /config package
The classpath root
It mentions current directory twice but this really doesn't mean anything:
I tried putting it in the root of my project (i.e. above src in the folder that matches the output of java.io.File( "." ).getCanonicalPath() and System.getProperty("user.dir");), and I tried putting it with the war files (i.e. in build\libs)
But the only place to put it that actually works is the default location (src\main\resources).
So what does "current directory" even mean and where do the files really go?
I need to find the correct external location for the files so I don't have to build database credentials into the app.
The guides say that putting application.properties in current directory will work and I found the exact current directory to put it in but it still doesn't work, which I can verify by the output of: System.out.println(System.getProperty("spring.datasource.url")); which is null It does output the correct value only with an embedded properties file.
According to ConfigFileApplicationListener:
// Note the order is from least to most specific (last one wins)
private static final String DEFAULT_SEARCH_LOCATIONS =
"classpath:/,classpath:/config/,file:./,file:./config/";
file:./ resolve to the working directory where you start the java process.
I agree with Stephane Nicoll's argument that we generally don't need this for development and test but needed for production where properties file is generally externalized and the one present in source code is not used. This is what works for me ,
java -jar myjar.jar --spring.config.location=file:D:\\RunRC\\application.properties
Directory - D:\\RunRC - mentioned in above command is sample from my machine.
I keep using properties file of source code i.e. from \src\main\resources\ in development and test but in production , I comment out entries and if I am starting my jar or war from D:\\RunRC then I provide Current Directory as shown in above java command and keep properties file there.
Just doing - #PropertySource({ "application.properties"}) or #PropertySource({ "file:application.properties"}) doesn't pick it up from the directory where jar or war is kept.
For database credentials, I would suggest to use OS specific environment variables and use syntax similar to - #PropertySource({"file:${CONF_DIR}database.properties" }) where CONF_DIR is existing environment variable pointing to that directory.
Hope it helps !!
I understand that the current directory is the root directory of your project. However, you can change this with -Dspring.config.location=your/config/dir/.
Have a look at this post enter link description here
If you search for "current directory java", you'll end up here with this question. The intention is that if you put an application.properties in the same directory as the application, it will be picked up by default.
You will not use that feature in development or for test as you shouldn't rely on that feature. But when running your app in production, it might be handy to put environment-specific settings in a configuration file that sits next to the application itself.
Current directory refers to where we execute our jar. Creating an executable jar via Spring Boot maven plugin and placing application.properties just beside the jar file will work. An example :here

Android - use ant to create build configurations that change configuration values

What I want is a way to have settings that are dependent on build configuration. To give a specific example, my android application connects to a web service. In development, I want the service url to be pulled in from a configurable value. In Test, I want a different value pulled in. In production, yet another value.
So, in code I have something like this:
public class HttpRequestHelper
{
private static String GetServiceUrl(ServiceAction action)
{
return serviceUrl + action.toString();
}
}
By default (when debugging/running through eclipse), I want that url to be http://localhost:1234
In Test I want https://test.mydomain.com
In Production I want https://mydomain.com
I am new to eclipse and ant and it has been a long time since I used java. How do I go about setting this up? What should the build.xml look like? I understand that when I want to build the test/prod versions I will need to use the command line. That's okay. But I don't know how to get this serviceUrl auto-set dependent on the build. I'm not even sure the best place to put this information (a resource, a properties file?). I really want to avoid setting it, building, setting it, building, etc.
As answers mentioned above says, you have to place the URLs in a property file like dev.properties, test.properties, prod.properties etc..
Now only thing that you need to do is making your build intelligent enough to choose a property file depending upon environment.
That can be done by passing a parameter to ANT, something like:
$ ant -file MyBuild.xml -DcurrentEnv=dev (For Development environment)
$ ant -file MyBuild.xml -DcurrentEnv=test (For Test)
$ ant -file MyBuild.xml -DcurrentEnv=prod (For Production)
Inside your build script, this is how you can include your property file:
<target name="jarMe">
<jar destfile="sample.jar" basedir="src" includes="${currentEnv}.properties"/>
</target>
With this in place, whatever name you supply at the time of build, property file with that name will be picked up.
You could try to have a following property file in your build.properties file:
service.url=*
And you could have http://localhost:1234 or https://test.mydomain.com in local.properties for your development and integration testing, and it could be set to https://mydomain.com in default.properties.
By do ing this, you have will get different value for service.url in different build environment. You could use that value to generate a config file, and parse it into your code, or set it to env variable, or just put it into a resource file, and Android will read it for you:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="service-url">##toben_to_be_replaced_during_build_time##</string>
</resources>
I would start by placing the urls into a properties file that you can then place onto the classpath. Make a test and a production properties file. Then depending on the build place the correct file onto the classpath and pull the properties at runtime.
Found a tutorial which goes through all the details of using ant to automate a build system, to create and use build configurations, as well as to build the release project with one command. Here it is: http://www.androidengineer.com/2010/06/using-ant-to-automate-building-android.html
Seems a little long, but it goes through all the steps and details involved.

Categories

Resources