SAP DBTech JDBC: [4321]: only secure connections are allowed - java

I am unable to create a connection with SAP Cloud Foundry HANA service from my Spring boot app. I have given JPA properties values as the information is provided in HANA HDI service binding in SCP CF but getting following error from my Sample Spring boot:
SAP DBTech JDBC: [4321]: only secure connections are allowed"
SAP CF HANA service is enforcing security is there any standard way to make connection with Spring boot to SAP HANA CF service?
Just to add connectivity is not working when making a connection in Springboot app via application.yml file by setting JPA properties, but was able to make a connection in a servlet using connection object by looking up the driver class manually via code.
How I can make a successful connection via JPA properties in application.yml file ?

try this for your data source url in application.yml:
jdbc:sap://{host}:{port}?encrypt=true&validateCertificate=false&currentschema={schema}

I have run into the exact same error.
Check your URL. In my case the URL looked similar to this one:
jdbc:sap://<host>:<port>?encrypt=true\u0026validateCertificate=true\u0026currentschema=D006A421632F47ED8A2C9346D28B67C2
Note the two occurrences of \u0026 escape sequences in the URL.
These should be & instead.
Once I changed them to & chars, it worked.
As previous answers noted, encrypt=true needs to be in the URL - but it won't be found if the & character is escaped.
If the URL contains the escape sequences, I would say it qualifies as a SAP HANA bug. Also, the error message is not really helping much. A message of Could not find encrypt=true in URL. Only secure connections are allowed! would have helped finding this more easily.

Issue seems to be known to SAP:
https://github.com/SAP/spring-cloud-sap/issues/8
There is at least a workaround listed on the end of the page, which might help.

Related

Dealing with DB instance IAM authentication token expiry

As per here after you generate an authentication token, it's valid for 15 minutes before it expires.
Consequently, if you don't hold onto the connection it will expire after 15 mins.
Upon application startup, we have code a bit like this:
Jdbi.create(dbProperties().getDbUrl(), jdbiProperties());
part of the jdbiProperties() method calls:
generator.getAuthToken(GetIamAuthTokenRequest.builder()
.hostname(url).port(PORT).userName(username)
.build());
We have a repo method that uses the jdbi (wrappper of a JDBC DataSource) like so:
jdbi.withHandle(handle ->
handle.createQuery("select name from contacts")
.mapTo(String.class)
.list());
The problem here is that since we generated the token upon startup it stop working after 15 min.
Is the some standard pattern for dealing with this? Seems like we could refresh the token upon every call (seems inefficient). Or we could request a new token upon receipt of expiry (through an exception).
Any suggestions appreciated.
TIA
Please see https://github.com/team-carepay/carepool-aws-jdbc
This library supports different ways of providing IAM authentication for RDS:
Wrapper for Tomcat Datasource
Wrapper for Hikari Datasource
Plugin for MariaDB driver
Plugin for MySQL driver
Depending on your project, you can pick any of the above options. For Jdbi, you can use Jdbc.create with takes a DataSource, e.g. Hikari or MySQL.
Please note that some versions of MariaDB driver support native AWS IAM (assuming that you have the AWS Java SDK in your classpath). Since that support was removed, you can now use https://github.com/awslabs/aws-mysql-jdbc which also supports IAM authentication. The MariaDB and AWS-MySQL drivers need a few libraries on the classpath (jackson, commons-collections, etc), so make sure you include these. The carepool-aws-jdbc plugin does not require any 3rd party libraries.

h2 database and sql server in spring boot

I was asked this question by a colleague, and I am unable to answer it:
I have an in memory database (h2), and I have a SQL database server which our app needs to talk too. But due to the two different SQL dialects we are now wondering how do we get around the issue by doing the least amount of work?
This to be done in spring boot. I am aware of how to connect to the h2 database and SQL database server, but I am unsure on the rest.
If everything is setup by Spring, you should not be worried about the 2 different SQL dialects. Just be sure that spring.jpa.database is set to default to let Spring autodetect the right dialect for each datasource.
Here's a link that explain how to use/initialize two datasource in a Spring Boot projet if you need some more information.

AWS RDS Proxy Connection from Java Spring Boot

We are using Java Spring Boot 2.3 alongside Postgresql as our database.
For better availability, we want to implement Multi A-Z and RDS Proxy for Postgresql.
In application.properties file, we are using the following properties for normal connection to the database and all works fine
spring.datasource.url=jdbc:postgresql://zzzz.us-east-1.rds.amazonaws.com:5432/postgres
spring.datasource.username=xxx
spring.datasource.password=yyy
When using RDS Proxy, i am trying to use same properties, but instead of the DB URL, i am using the endpoint of the RDS Proxy
spring.datasource.url=jdbc:postgresql://rds-proxy-endpoint.us-east-1.rds.amazonaws.com:5432/postgres
spring.datasource.username=xxx
spring.datasource.password=yyy
For testing purposes, RDS Proxy Security group is open and my machine has access to it, but still it wont let me connect, here is the error
24832 [task-1] ERROR com.zaxxer.hikari.pool.HikariPool --- HikariPool-1 - Exception during pool initialization.
org.postgresql.util.PSQLException: The connection attempt failed.
Am i missing something?
Thanks a lot in advance

Choose JDBC database depends on logged user

I have a simple spring boot application. I am using JDBC connection configured by JDBC Template (JDBC url is got from properties file).
Can you tell me how to reach following thing:
JDBC Connection should be established in depends on logged user, I have a problem with projecting in spring such flow of control that object jdbc template will be created after loggining user.
It is about different users use different database.
Can you help me, please?
You can do the routing at the datasource level.
See https://spring.io/blog/2007/01/23/dynamic-datasource-routing/
And
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.html

Datasource creation failed using PCF User Provided Service

I have a SpringBoot application and deploying it in PCF where app is trying to connect Oracle 12c Database using PCF User Provided Services but it failing with this error Failed to determine a suitable driver class
build.gradle code:
and here are the configuration that I used in CUP service:
Service binding is happening properly. I can see the same details under VCAP_SERVICES in Environment Variables.
Error:
Short Answer: I think you want the uri to be oracle://... Strip off the jdbc: part. The Spring Autoreconfiguration code that gets injected by the Java buildpack will look at the prefix on the URI, so it needs oracle:// to know it's an Oracle link.
Long Answer: You probably don't want to depend on the injected Spring Autoreconfiguration. When it just works, it's great, but it can be difficult to understand what it's doing when it doesn't work.
It is better to use Spring Cloud Connector or even better, as all signs point to this replacing Spring Cloud Connector, use java-cfenv. For details on java-cfenv, see this blog post.
Spring Cloud Connector has the same issue I mentioned above as the Spring Autoreconfiguration, except that it will pretty clearly tell you when it doesn't recognize a bound service. Anyway, if you decide to use SCC, make sure you prefix the URI with oracle://.
If you use java-cfenv, it's more flexible so it's really up to you what properties and values you inject through the service.
Hope that helps!

Categories