How to connect to online MongoDB database from Spring Boot? - java

I want to connect to an online MongoDB database hosted at Mlab, from inside a Spring Boot application.
I have configured the application.properties with the URI:
spring.data.mongodb.uri = mongodb://myuser:mypassword#ds129532.mlab.com:29532/consilium-dev
However, the application still connects to the local MongoDB database. How can I make it connect to the Mlab database?
SOLUTION:
The resources folder was not situated in the right folder. It should be in src/java/resources

In my case, spring boot was connecting to the uri specified in application.properties file while testing in my PC but once deployed to heroku, it always connected to the localhost irrespective of what was specified in application.properties. Solution was to pass the database uri as command line arguments while deploying the jar to the server because this will take precedence over the properties. To do so, create a Procfile like:
web: java -Dserver.port=$PORT -Dspring.data.mongodb.uri=mongodb://<user>:<pass>#<host>:<port>/<db> -jar my-app.jar
And using heroku toolkit, run following command.
heroku deploy:jar -j my-app.jar -i Procfile --app <host-name>

Using database values in the application.properties didn't work for me for online mongodb.
It works fine for local db. But Once I google and found an example online where they added it in this way below and it worked for me.
spring.data.mongodb.uri=mongodb://<USERNAME>:<PASSWORD>#ds261828.mlab.com:61828/springdb.

Related

Override Spring boot properties in docker container

I have a spring boot application that is dockerized. By default the application has spring.cloud.config.enabled=false hence the application doesn't pick up the application.properties from configserver. However while deploying in a separate env we need to integrate the application with configserver so we need to override and set the spring.cloud.config.enabled property to true.
To achieve this I am running the docker image using the following docker-compose file :
version: '3'
services:
my-app-new:
container_name: my-app
image: my-app:1.0.0-SNAPSHOT
ports:
- "8070:8070"
environment:
- SPRING_CLOUD_CONFIG_ENABLED=true
- SPRING_CLOUD_CONFIG_URI=http://localhost:14180
However, it just doesn't work. If I hard code the values in the property file then it integrates fine.
I also tried the following command but it still didn't work :
docker run -p 8070:8070 -e SPRING_CLOUD_CONFIG_ENABLED=true -e SPRING_CLOUD_CONFIG_URI=http://localhost:14180 my-app:1.0.0-SNAPSHOT
The spring boot version is 2.2.6.
Let me know what the problem is.
Update :
I cannot use profiles as there too many env in our company and even the VMs keep getting changed so cannot have hardcoded profiles. We want a solution where we can just pass certain variables from the outside.
As someone pointed out in the comments the above compose yml is not working as the environment variables need to read by the spring boot application. So did some research on the internet and instead we are now passing the JAVA_OPTS tomcat variable while running the image. Like so :
docker run --env JAVA_OPTS="-Dspring.cloud.config.uri=http://localhost:14180 -Dspring.cloud.config.enabled=true" -p 8080:8080 my-app-image
And in the docker file we have used the JAVA_OPTS while starting the jar like so
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar app.jar" ]
And this still doesnt work. Not sure what is going wrong.
I found the problem with my setup. I made a silly error. The config server is not in my docker network and I used localhost to communicate with the config server. Localhost would of course mean that I am referring to the app containers IP which only has the app running. Instead when I used the ip address or the hostname of my machine my application container could connect to the config server successfully.
Why you not run container --> go inside --> change configuration and commit to new images.
After that deploy to new env.

Pass environment variable on AWS Elastic Beanstalk for Spring Boot App using Jasypt

I was deploying my Spring Boot Application on AWS Elastic Beanstalk. My web app is using Jasypt, so in the application.properties file, I wrote down jasypt.encryptor.password=, currently the password in this file is empty, I want to pass the password as a variable on AWS Beanstalk's configuration.
When testing locally, I used java -jar myapp.jar --jasypt.encryptor.password=1234 in command line, and it ran successfully. However, when deploying on AWS, I added jasypt.encryptor.password in environment properties and set its value to 1234, the app failed to run. The log said I cannot set the password as empty. So, at this point Beanstalk did not read the environment property I just set. But it can really read the properties later because I tested it after setting another property and used GET API to print it.
My question is: how to make Elastic Beanstalk run/read the environment properties at the beginning? In other words, how to make EB run java -jar myapp.jar with --jasypt.encryptor.password=1234attached?
Thank you so much in advance!
Procfile can't use environment variables. Use a shell script to start the application instead of invoking java -jar directly in Procfile.
Procfile:
web: /bin/sh start_server.sh
start_server.sh
#!/bin/bash
JAVA_OPTS='-Djasypt.encryptor.password=1234'
exec java $JAVA_OPTS -jar myapp.jar
references: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/platforms-linux-extend.html

How can I deploy a java web app to heroku?

I have a Java web app with Tomcat embedded in my jar file. I can containerize the app with Docker and run it with command java -jar -myapp.jar, but I can't run that container in Heroku. I tried using heroku CLI to dockerize and deploy, but Heroku gives me an error of "can't access jarfile".
I tried to fix this by using heroku deploy:jar to deploy my fat jar, but this erroneously gives me an error:
heroku deploy:jar target/*.jar -a medscanner2
-----> Packaging application...
- app: medscanner2
- including: target/medscanner2.jar
! ERROR: Could not get API key! Please install the Heroku CLI and run
`heroku login` or set the HEROKU_API_KEY environment variable.
! Re-run with HEROKU_DEBUG=1 for more info.
!There was a problem deploying to medscanner2.
!Make sure you have permission to deploy by running: heroku apps:info -a
medscanner2
I am signed into Heroku and I can use heroku auth:whoami to verify that, I can push containers and deploy them, so this error doesn't make any sense. I reran with HEROKU_DEBUG=1 and it did not return any more info.
I further tried to set the HEROKU_API_KEY variable in the CLI with a token I got from Heroku and this still caused the same error when I try to deploy the jar.
I am using a Procfile (although I am not sure it is necessary):
web: java -Dserver.port=$PORT -jar target/medscanner2.jar
Since the issue seems to be indicating there is an issue with access I don't see how the Procfile could be influencing it.
What is the best way for me to deploy a Java web app that does not using Spring Boot to Heroku? I have separately deployed the docker container successfully to Google app engine, so all this work for Heroku is very frustrating.
I ended up fixing this by using webapp-runner to deploy my app. It runs the webapp-runner jar which can run your .war files. This required adding the heroku-maven-plugin and maven-dependency-plugin.
I could then add a Procfile: web: java -jar target/dependency/webapp-runner.jar target/*.war --port $PORT
and use the Heroku CLI to add the app using git. The link with webapp-runner is a guide to deploying tomcat java apps with webapp-runner.

Docker container is only able to access MSSQL running inside another container with the internal IP/port

I have deployed a very simple MSSQL docker container using the following docker run command :
docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=NotYourBusiness" -p 2433:1433 --name sql1 -d mcr.microsoft.com/mssql/server:2017-latest
I have SSMS installed on my machine and i'm able to connect to this instance with the following URL :
MyHostName,2433
I am able to run my spring boot app from my machine also with the following connection string :
dataSource.setJdbcUrl("jdbc:sqlserver://localhost:2433;database=SomeDatabase;");
With only MSSQL in a docker container, my application works perfectly from my machine.
Now, i want to put my spring boot app into a container as well. I have therefore built the following docker file :
FROM openjdk:11-jre-slim
VOLUME /tmp
EXPOSE 8082
ADD target/tno-1.0.jar tno-1.0.jar
ENTRYPOINT ["java","-jar","tno-1.0.jar"]
This is the build command i use to create the image :
docker build -f Dockerfile -t tno .
And this is the command i use to build the container :
docker run -t --name tno --link sql1:mssql -p 8082:8082 tno
Using the same connection string that works on my machine, the spring boot app fails to start with a connection refused error. I did look at many posts and they pointed out that the term "localhost" no longer really applies when running from a container since it refers to that container only. The only way i was able to make it work is to replace localhost:2433 with the container IP address : 1433.
This is perfectly acceptable but is there a way for a container to behave like my dev machine and be able to connect to another container as if the connection was coming from the outside world?
Thanks
If you can access to the database from the application running in other containers, try to configure your jdbc url from localhost to mssql (name of db link).
jdbc:sqlserver://mssql:2433;database=SomeDatabase;
Let me know or check this how to link container in docker?

spring.cloud.inetutils.ignoredInterfaces ignored in profiles

I'm running a Spring Boot application and using the Netflix OSS Spring Cloud framework. We are running a Eureka instance and have a service that is trying to register. When our service registers to Eureka it uses IP of the wrong port name. To fix this we have added:
spring.cloud.inetutils.ignoredInterfaces=eth0
This works great when we pass this from the command line, but when we move this into a profile configuration it doesn't work but all other configuration of the profile is picked up.
So for example this will work:
java -jar service.jar --spring.cloud.inetutils.ignoredInterfaces=eth0
and this will NOT work:
java -jar service.jar --spring.profiles.active=localvm
where application-localvm.properites contains:
spring.cloud.inetutils.ignoredInterfaces=eth0
Look you have to add -D argument before the main class or jar archive.
So try this:
java -jar -Dspring.profiles.active=localvm service.jar
For more details check this doc about how to set the active Spring profiles.

Categories

Resources