Spring Boot switch between multiple databases (data-sources) - java

I have a spring boot REST API application for a project with 2 different setups ( =2 different jars). Both need to be realized, but I have no idea on how to do it or what the best way would be.
Both setups need to have a connection with an online database (on a server; AWS) and a connection with an offline or local database (running on the machine/pc itself). It is the offline or local connection that is different between both setups.
Setup 1:
When the application is started it needs to connect to the online database. When an error occurs or connection to the online database is lost, it needs to connect to the offline/local database.
It is not required that that it will reconnect with the online database after an error occurred or the connection was lost.
Setup 2:
When the application is started it needs to connect to both the online and the offline database. So when the user does a post to the REST API, both the online and the offline database need to be updated (unless an error occurs or the connection to the online database is lost). If the user just does a get request, it is preferred to get the data from the online database, unless an error occurs or the connection to the online database is lost, than it can use the offline database.
It is not required that that it will reconnect with the online database after an error occurred or the connection was lost, but in this setup it would be nice.
Synchronizing the data after connection has been established again isn't required either (but would maybe be a nice feature).
I have seen a similar post where the solution was to use ha-jdbc but it is an old post... Maven just doesn't find the dependency when I try adding it to my pom.xml file.
After some more searching and trying I was able to add ha-jdbc to my pom.xml. What I had to do was add a repository that contained ha-jdbc.
<project>
<repositories>
<repository>
<id>jbossrepository</id>
<name>jbossrepository</name>
<url>https://repository.jboss.org/nexus/content/repositories/thirdparty-releases/</url>
</repository>
</repositories>
<dependency>
<dependency>
<groupId>net.sf.ha-jdbc</groupId>
<artifactId>ha-jdbc</artifactId>
<version>3.0.3</version>
</dependency>
</dependency>
</project>
Yet to see if I can get it to work and if it is what I am looking for...
ha-jdbc isn't worth trying, one error or problem after the other, it's just old java too...
Versions:
- java: 1.8
- org.springframework.boot (spring-boot-starter-parent): 2.1.8.RELEASE
- Database (online & offline): PostgreSQL 11.5

Take a look this example code. There you can find already implemented a working solution.
The logic behind it is EnableJpaRepositories which enables it based on packages (basePackages)

Related

How to use mongoDb in spring boot? No SRV records available for host error

I try to use the MongoDB in the spring-boot project.
I tried a different of non-usable tutorial and stopped on the official documentation
I created cluster and now I ready to use MongoDB in my project.
Documentation says:
As I understand the pwd - this is the password, so my application.properties looks like:
spring.data.mongodb.uri=mongodb+srv://root:pass#88.155.XX.XXX.mongodb.net/mygrocerylist
spring.data.mongodb.database=mygrocerylist
this is all what I added to the application.properties - there are no other information in the tutorial.
After I started project, I receive error, that repeats every several seconds (however project still launched - I receive error even during system logging):
com.mongodb.MongoConfigurationException: No SRV records available for
host 88.155.21.126 at
com.mongodb.internal.dns.DefaultDnsResolver.resolveHostFromSrvRecords(DefaultDnsResolver.java:64)
~[mongodb-driver-core-4.4.2.jar:na] at
com.mongodb.internal.connection.DefaultDnsSrvRecordMonitor$DnsSrvRecordMonitorRunnable.run(DefaultDnsSrvRecordMonitor.java:78)
~[mongodb-driver-core-4.4.2.jar:na] at
java.base/java.lang.Thread.run(Thread.java:829) ~[na:an]
please, can anyone to explain how to exactly add MongoDB to the spring project?
I prefer to use such solution, since I need to complete the task and launch my project in the another PC. In any case - I tried to use mongoDb in the docker and this way also not work for me, and I not sure the other side use MongoDB locally.

error while running spring boot app on localhost

I'm trying to run my spring boot applicationon localhost ,normally i should get Whitelabel error page for the first time,but i got this error while running it.
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
Process finished with exit code 1
As shown in your log, you try to run the application without providing information about the database.
Spring and Spring-boot are not entirely based on magic.
They can guess some database information, like the url if you use an embedded datasource (as mentioned in the log you provided). Have this dependency on your classpath if you want to run your application with an in-memory database:
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
</dependency>
Make sure there is not the <scope>test</scope> in this dependency. And, at runtime, spring-boot will automatically connect to your hsqldb database.
If you are running your application and you have a production oriented database, like PostgreSQL for instance, then spring-boot can't guess what is the connection information, like the url or the database name. And you have to provide this properties in the application.properties file:
spring.datasource.url=jdbc:postgresql://<database_host>:<port>/<database_name>
spring.datasource.username=myUser
spring.datasource.password=secret
spring.datasource.type= (Not necessary)
If you don't provide that, it's like posting a mail without giving any adresses... you can't find the person you are looking for.
Hope it helps !
As the log depicts, you have to review your data-source configs, and make sure all good.

Spring Boot-Activiti Integration with Sybase Database

I created a spring-boot project to read and write data to Sybase database. The project was working as intended. However, whenever I added activiti dependencies, It says "couldn't deduct database type from database product name 'Adaptive Server Enterprise'". According to my understanding, there are some classes conflicting each other in activiti and spring even though I do not use anything regarding activiti( except the fact that I just opened a folder called processes in the resources directory).
The activiti dependencies I added are:
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>5.21.0</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-rest-api</artifactId>
<version>5.21.0</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-actuator</artifactId>
<version>5.21.0</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-jpa</artifactId>
<version>5.21.0</version>
</dependency>
To clarify my point in this, I wanted to use activiti just for workflow purposes and leave the rest of the ETL or database job to spring. If I change database from Sybase to Mysql, the project also works fine even with activiti dependencies. As far as I know activiti has no support for Sybase and apparently, it tries to interfere everything possible and overrides something that was already working at the first place. How can I overcome this problem?
you are trying to use the spring boot starter which automatically tries to configure a database using spring autoconfiguration. Can you clarify with which database do you want to use Activiti? If you want to use Sybase you will need to contribute back to the project with Sybase support. Alternatively, you can not use the starter and depend on the engine directly, this will push you to provide the engine configurations for your spring environment. You can also check the -starter project and adapt as needed.
HTH

AppEngine Managed VM with Java and Cloud SQL

I want a Java Appengine Managed VM application to connect to a 2nd Gen Cloud SQL Instance. There are discrepancies in the documentation - I can't figure out if this is actually supported by Google or not!
https://cloud.google.com/appengine/docs/managed-vms/java/using-cloud-sql
states:
4: In the console, grant your App Engine application access to the Google Cloud SQL instance.
But I see no way of doing this. In the Cloud SQL management console, under properties of an instance, there is:
Authorized applications: None
and seemingly no way to authorize applications?
Then on this page https://cloud.google.com/sql/docs/dev-access it states:
Java App Engine Applications
Using the Cloud SQL Proxy is not supported for Java.
So you seemingly cant use the Cloud SQL proxy. The only way I have got it all working is to open the SQL port to the world, so that the managed VM instances can connect to it on its public IP address, but that is a horrific solution!
Is there an actual supported way of doing this? Anyone from Google able to answer?
April 2016 Update
We have a new Java library for connecting to Cloud SQL instances from Managed VMs and other environments: https://github.com/GoogleCloudPlatform/cloud-sql-mysql-socket-factory
It's still very new so the usual caveats apply, but we haven't found any issues in our testing.
Old answer:
I think the best option right now is to use the junixsocket library as explained in this post: https://stackoverflow.com/a/34820600
If you are using the maven-war-plugin to package your application, then adding the following two dependencies should be enough:
<dependency>
<groupId>com.kohlschutter.junixsocket</groupId>
<artifactId>junixsocket-mysql</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>com.kohlschutter.junixsocket</groupId>
<artifactId>junixsocket-native-common</artifactId>
<version>2.0.4</version>
</dependency>
For Play Framework, add the following dependencies:
libraryDependencies += "com.kohlschutter.junixsocket" % "junixsocket-mysql" % "2.0.4"
libraryDependencies += "com.kohlschutter.junixsocket" % "junixsocket-native-common" % "2.0.4"
Configure your Play application.conf as follows:
db.default.url="jdbc:mysql:///mydb?socketFactory=org.newsclub.net.mysql.AFUNIXDatabaseSocketFactory&junixsocket.file=/cloudsql/PROJECT_ID:REGION:INSTANCE_NAME"
We hope to offer something in the future that does not require the use of junixsocket or a similar library.
We'll review/fix the documentation at https://cloud.google.com/appengine/docs/managed-vms/java/using-cloud-sql as it has some issues. Thanks for bringing it to our attention.
I did finally get it running with a managed VM with this xml:
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>thmadmin-ben</application>
<version>master</version>
<threadsafe>true</threadsafe>
<vm>true</vm>
<precompilation-enabled>false</precompilation-enabled>
<manual-scaling>
<instances>1</instances>
</manual-scaling>
<beta-settings>
<setting name="cloud_sql_instances" value="xxx-ben:us-east1:yyy"/>
</beta-settings>
</appengine-web-app>
But after following the rabit hole I dont think its going to be easy to swap out the TCP database connector with the socket based one in the framework Im using (play framework).
REALLY would love to be able to define "allowed" AppEngine projects in the Cloud SQL instance settings - without this ability Im going to have to run on AWS...

Have jetty instance (configured through maven) connect to mysql

Just a quick question but I have been struggling for a while with this now - any help would be appreciated. I have just managed to get my first jetty instance running by setting it up using maven. Now it runs successfully using mvn jetty:run.
However, I need to have the jetty instance connect to a mysql database. How can I do this? all online documentation I have read refers to a start.ini file but I am doing everything through maven so am not sure how this applies. Has anyone got a simple list of instructions of what I would need to do to have my app connect to mysql? Preferably using a connection pool.
Thanks for any help you can offer
If you don't need to use a connection pool so I just recommend you write the code to connect it to MySQL.
first, you will need to import mysql-connector from maven
Add at this few lines to your pom.xml
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
Then if you have created a class that manages the connection to your database. And you don't care much about pooling your connections then
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://{IP_TO_YOUR_SERVER}:{PORT[DEFAULT=3306]}/{DB_NAME}?user={USERNAME}&password={PASSWORD});
However, if you want to use a connection pool you probably will need to check "Jetty/Howto/Configure JNDI Datasource"
And I think this link to stack overflow can help as well.
JNDI lookup failing with Jetty for JDBC connection pooling with MySQL?
I have been struggling all morning with the same issue and to be honest I tried the first approach. And this moment I am using that solution.

Categories

Resources