Connecting Azure app service to MongoDB Atlas across vnet peering connection - java

So I have an Azure App Service and I want it to be able to connect to mongo db atlas. For our Atlas setup there is a peering connection between our managed environment on azure (and the vnet it all sits in) and our mongo db cluster.
The mongo cluster is setup with "Connect via peering only" which we can't change. This means we can't connect to our db with any old public ip address -It has to come from the vnet it's peered with. The vms (from within the peered vnet) are able to access the db no problem.
I tried with the app service to connect to the db with the same connection string that worked for the vm. It returned a the error:
java.net.ConnectException: Connection refused (Connection refused)}}, {address=MYMONGOADDRESS.mongodb.net:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused (Connection refused)}}]
This is expected due to the reasons above. However I setup the vnet integration for the app service
. I created a dedicated subnet as described for the app service and whitelisted the ip range in mongo. However I still couldn't connect to the db after using this vnet integration. I also got a very similar error but slightly different.
{java.net.SocketTimeoutException: connect timed out}}, {address=MYMONGOADDRESS.mongodb.net:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.SocketTimeoutException: connect timed out}}]
Where instead of a connection refused I'm not getting a connection time out. I've repeated this a few times and get the same result.
Anyone know why these errors are different and any help in being able to connect to the db from my azure app service?

Is there any firewall or network security group? What the network peering status is? If it shows « initiated » then this means it has not been completed. Network peering has to be done on each ends. If it shows « connected », then I would look for firewall or network security groups.
See this
https://docs.atlas.mongodb.com/security-vpc-peering/#vpc-peering

No idea if this can apply to your case but this question was the first and only that came up when I was searching for something similar.
In my case I have a MongoDB Atlas deployed on Azure and an app running in AKS. I set up peering as documented but still could not connect from the app container in AKS to the MongoDB. Turns out the problem was an incorrect connection string.
Atlas has a different URL when connecting directly and when connecting through a peer network:
# Direct connection
mongo "mongodb+srv://<cluster>.<something>.mongodb.net/<dbname>"
# Peered connection (note the -pri)
mongo "mongodb+srv://<cluster>-pri.<something>.mongodb.net/<dbname>"
As an additional note, I configured the Atlas Network Acces IP address list with the CIDR of the Azure VN Subnet used in AKS. (Under Virtual Network > Subnets > IPv4)

Related

Play framework java connection is not available to sql server database

I'm stucked in a problem during connection from my java project (play framework ) to a sql server database in Azure.
In local enviroment the connection works fine.
Below parameter in my application.conf :
db.default {
url="jdbc:sqlserver://server-name.database.windows.net:1433;database=database-name"
encrypt=true
trustServerCertificate=false
hostNameInCertificate="*.database.windows.net"
loginTimeout=30
driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
username="root"
password="RootPwd"
}
This is the error received:
ERROR o.h.e.jdbc.spi.SqlExceptionHelper HikariPool-1 - Connection is
not available, request timed out after 30006ms. ERROR
o.h.e.jdbc.spi.SqlExceptionHelper The TCP/IP connection to the host
par-sql-server.database.windows.net, port 1433 has failed. Error:
"par-sql-server.database.windows.net. Verify the connection
properties. Make sure that an instance of SQL Server is running on the
host and accepting TCP/IP connections at the port. Make sure that TCP
connections to the port are not blocked by a firewall.". ERROR
p.api.http.DefaultHttpErrorHandler
play.api.PlayException: Execution exception[[CompletionException:
org.hibernate.exception.JDBCConnectionException: Unable to acquire
JDBC Connection]]
at play.api.http.HttpErrorHandlerExceptions$.$anonfun$convertToPlayException$3(HttpErrorHandler.scala:388)
at scala.Option.getOrElse(Option.scala:201)
at play.api.http.HttpErrorHandlerExceptions$.convertToPlayException(HttpErrorHandler.scala:388)
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:373)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:264)
at play.core.server.AkkaHttp
I have already checked that tcp/ip port 1433 is correctly available for database, and my ip is correctly setted to avoid firewall.
Any suggestions?
thanks
Usually this error occurs when the database is not getting the connection within the default connectionTimeout property.
You can try to increase the value of connectionTimeout in Java config as below:
config.setConnectionTimeout(300000);
below is one of the sample config:
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(20);
config.setConnectionTimeout(300000);
config.setConnectionTimeout(120000);
config.setLeakDetectionThreshold(300000);
If possible let me know the steps to reproduce this issue so that I can fix it accordingly, also based on the information you've provided these blogs (Blog1, Blog2) will help you in establishing the connection

External connection to Mongodb cluster in kubernetes

I've used mongo k8s sidecar to provision a 3 member replica set mongo cluster on kubernetes. I need to expose mongodb service externally and hence created a LoadBalancer.
This is how the service looks like
LoadBalancer Ingress: xxx.yyy.elb.amazonaws.com
Port: <unset> 27017/TCP
TargetPort: 27017/TCP
NodePort: <unset> 30994/TCP
Endpoints: 100.14.1.3:27017,100.14.1.4:27017,100.14.2.5:27017
Trying to connect using mongodb shell 3.6 works fine
mongo --host xxx.yyy.elb.amazonaws.com
But in the java client code I see the following exception.
java.net.UnknownHostException: mongo-1.mongo.dev.svc.cluster.local
I can confirm that the mongo pods are up and running. I am able to connect to mongo from other pods within the cluster - just not able to reach it externally.
Few things I don't understand is whats exactly happening in the java client.
The java client (which uses spring-data-mongo for configuration) is being created as follows.
MongoClient mongoClient = new MongoClient( "xxx.yyy.elb.amazonaws.com" , 27017 );
The fullstack trace is as follows
Caused by: com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches com.mongodb.client.internal.MongoClientDelegate$1#161f6623. Client view of cluster state is {type=REPLICA_SET, servers=[{address=mongo-2.mongo.dev.svc.cluster.local:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketException: mongo-2.mongo.dev.svc.cluster.local}, caused by {java.net.UnknownHostException: mongo-2.mongo.dev.svc.cluster.local}}, {address=mongo-0.mongo.dev.svc.cluster.local:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketException: mongo-0.mongo.dev.svc.cluster.local}, caused by {java.net.UnknownHostException: mongo-0.mongo.dev.svc.cluster.local}}, {address=mongo-1.mongo.dev.svc.cluster.local:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketException: mongo-1.mongo.dev.svc.cluster.local}, caused by {java.net.UnknownHostException: mongo-1.mongo.dev.svc.cluster.local}}]
at com.mongodb.internal.connection.BaseCluster.createTimeoutException(BaseCluster.java:401)
at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:120)
Why is the mongoClient using the pod name , even though I've passed the loadbalancer address? How do I fix this?
Thanks in advance
You are getting an error for mongo-1.mongo.dev.svc.cluster.local and that's the internal endpoint within the cluster. In other words, that's how you would get to your Mongo instance from other pods in the cluster.
On the Java client, you need to use xxx.yyy.elb.amazonaws.com:27017 as the Mongo endpoint configuration.
Something like this:
MongoClient mongoClient = new MongoClient( "xxx.yyy.elb.amazonaws.com" , 27017 );
To give you an overview of the path, your Mongo instance is exposed through a LoadBalancer Kubernetes Service on port 27017.
Then the traffic comes into the load balancer and from there gets forwarded to your endpoints 100.14.1.3:27017, etc.
Then from there, they enter the Node on the NodePort 30994 on each node.
Then the nodes that have a pod running reply with an answer.
The Mongo process in the container itself runs on port 27017 so the moment the traffic gets to the node on port 30994 the container runtime forwards the traffic to your application in the container to 27017.

java.sql.SQLException: The application requester cannot establish the connection

I have written a java program to connect to AS400 DB. I am using jt400-6.4.jar to connect to DB.
DB Properties I am using:
as400_dbUrl=jdbc:as400://host/schema;translate binary=true
as400_dbUser=user
as400_dbPassword=pass
My program is not able to connect to DB server i am getting the below error.
2017-06-30 05:36:53 ERROR DBUtil:88 - Exception:
java.sql.SQLException: The application requester cannot establish the connection. (A remote host refused an attempted connect operation.)
at com.ibm.as400.access.JDError.throwSQLException(JDError.java:528)
at com.ibm.as400.access.AS400JDBCConnection.setProperties(AS400JDBCConnection.java:3130)
at com.ibm.as400.access.AS400JDBCDriver.prepareConnection(AS400JDBCDriver.java:1360)
at com.ibm.as400.access.AS400JDBCDriver.initializeConnection(AS400JDBCDriver.java:1211)
at com.ibm.as400.access.AS400JDBCDriver.connect(AS400JDBCDriver.java:352)
at java.sql.DriverManager.getConnection(DriverManager.java:426)
at java.sql.DriverManager.getConnection(DriverManager.java:474)
I googled about this, not able to find the exact reason.
I think jt400.jar will use 8471 as the port to connect to DB. Please correct me if I am wrong regarding this port.
I am not able to ping the host. ping host is not returning any response.
I am able to telnet like telnet host. But I am not able to telnet the system like telnet host 8471
Your hlep will be highly appreciable. Kindly help.
try updating your DB property as:
Add <:port-number> after host
as400_dbUrl=jdbc:as400://host:port/schema;translate binary=true
Hope this solves your problem.

spring server cannot connect to redis using jedis client

I am getting this issue when I deploy redis server and spring server in two different servers and try to connect to spring server through my application.
App Details:
We have mobile application which publish gps coordinates to spring server using stomp. In the spring server we create jedis pubsub connection and publish those gps data to our web application and web users subscribe to those jedis pubsub connections.
Library versions:
stomp:1.7.1
jedis: 2.8.1
spring: 4.3.0
Working scenarios:
*Deploy spring server in my local machine and redis server in remote production server.
*Deploy spring server in remote server and redis server in same remote server where spring server is deployed.
Partially Working scenarios:
*Deploy spring server in remote server and redis server in different remote server where spring server is deployed. In this scenario I monitor redis server using redis cli and I can see the "HGETALL", "PUBLISH" key words with its data. But the same time I got following error in spring server:
Caused by:
java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at redis.clients.jedis.Connection.connect(Connection.java:158)
... 4 more
redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused)
at redis.clients.jedis.Connection.connect(Connection.java:164)
at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:80)
at redis.clients.jedis.Connection.setTimeoutInfinite(Connection.java:68)
at redis.clients.jedis.Jedis.subscribe(Jedis.java:2626)
at shipxpress.pubsubservice.controllers.SubscriberThread.run(MainController.java:227)
The spring server can successfully depoyed to the server and exception occurs when jedis try to publish or subscripe to the connection.
I can succesfully ping to redis server from the server where we deploy the spring server through the redis-cli and the redis server prtected-mode is no and and bind ip is set to 0.0.0.0
Links:
I went through following links but no luck
Redis bind to more than one IP
https://github.com/xetorthio/jedis/issues/1405
Cannot connect to redis using jedis
This issue means that the Spring remote server is not able to communicate with the other remote server(Redis server) on the default Redis port.
Maybe you could confirm this by trying to access the Remote Redis server from the other remote Server using netstat from the console.
I had the same issue, and the simplest solution was
Find the following line in your redis.conf file and comment it out:
bind 127.0.0.1
By adding a # in front of it:
# bind 127.0.0.1
and change the line protected-mode yes to be protected-mode no
save your redis.conf and restart redis using the config file
redis-server /configFileLocation

Connecting Application to OpenShift MongoDB

I had a MongoDB on MongoLab, which I was using with my Android Application and everything was just fine.
But well, they decided to upgrade the MongoDB version to 3.0.x and now I’m not able to connect again because the java driver 3.0 don’t seem to work very well on Android. We can see some discussion about the situation here: mongodb 3.x driver Android compatibility
Then I decided to try OpenShift, which has version 2.4 of MongoDB.
But I’m not being able to connect to the database like I use to do with MongoLab. I feel like I might be misunderstanding the purpose of OpenShift.
Caused by: java.net.ConnectException: Connection refused: connect
[...]
Exception in thread "main" com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}. Client view of cluster state is {type=UNKNOWN, servers=[{address=127.XX.XXX.X:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused: connect}}]
Does anyone have any experience with OpenShift that could give me some advice?
If OpenShift is not an option, could anyone give some suggestion about a free MongoDB cloud service that is not 3.0.X+?
Just would like to remind that this is for college study that’s why we are not investing money on it.
Thanks in advance.

Categories