UnknownHostException when connecting to Azure Cosmos DB using Cassandra - azure

I followed the official instructions of Azure Portal. This is my
config.properties:
cassandra_host="demodemodemo.cassandra.cosmosdb.azure.com"
cassandra_username="demo"
cassandra_password="aHaplLoWhRlysBrtJWiOwB79TkqSU9PjKLu5wDeltLqys5NpR9vmtHCJrTF4ScdY69yNSWUvTUphax8RijydTA=="
cassandra_port=10350
ssl_keystore_file_path=
ssl_keystore_password=
Then it throws java.lang.IllegalArgumentException: Failed to add contact point and Caused by: java.net.UnknownHostException: "demodemodemo.cassandra.cosmosdb.azure.com" at this point:
[ CassandraUtils class, getSession() method ]
cluster = Cluster.builder()
.addContactPoint(cassandraHost)

You need to remove the double quotes from the settings.
If your credentials are correct, this should work.
cassandra_host=demodemodemo.cassandra.cosmosdb.azure.com
cassandra_username=demo
cassandra_password=aHaplLoWhRlysBrtJWiOwB79TkqSU9PjKLu5wDeltLqys5NpR9vmtHCJrTF4ScdY69yNSWUvTUphax8RijydTA==
cassandra_port=10350
Also by default the username is the same as the first part of the host so in your case demodemodemo except if you changed it.

I had similar problem. My corporate on prem environment is behind a proxy. Since I was using cassandra, I could not setup a http-proxy (it has its own protocol). The solution might be to use Azure Private Link. An example tutorial on how to do it is here: https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-configure-private-endpoints

Related

Spring Boot app can't connect to Cassandra cluster, driver returning "AllNodesFailedException: Could not reach any contact point"

i've updated my spring-boot to v3.0.0 and spring-data-cassandra to v4.0.0 which resulted in unable to connect to cassandra cluster which is deployed in stg env and runs on IPv6 address having different datacenter rather DC1
i've added a config file which accepts localDC programatically
`#Bean(destroyMethod = "close")
public CqlSession session() {
CqlSession session = CqlSession.builder()
.addContactPoint(InetSocketAddress.createUnresolved("[240b:c0e0:1xx:xxx8:xxxx:x:x:x]", port))
.withConfigLoader(
DriverConfigLoader.programmaticBuilder()
.withString(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER, localDatacenter)
.withString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD,password)
.withString(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT,"10s")
.withString(DefaultDriverOption.CONNECTION_CONNECT_TIMEOUT, "20s")
.withString(DefaultDriverOption.REQUEST_TIMEOUT, "20s")
.withString(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, "20s")
.withString(DefaultDriverOption.SESSION_KEYSPACE,keyspace)
.build())
//.addContactPoint(InetSocketAddress.createUnresolved(InetAddress.getByName(contactPoints).getHostName(), port))
.build();
}
return session;`
and this is my application.yml file
spring:
data:
cassandra:
keyspace-name: xxx
contact-points: [xxxx:xxxx:xxxx:xxx:xxx:xxx]
port: xxx
local-datacenter: xxxx
use-dc-aware: true
username: xxxxx
password: xxxxx
ssl: true
SchemaAction: CREATE_IF_NOT_EXISTS
So locally I was able to connect to cassandra (by default it is pointing to localhost) , but in stg env my appplication is not able to connect to that cluster
logs in my stg env
caused by: com.datastax.oss.driver.api.core.AllNodesFailedException: Could not reach any contact point, make sure you've provided valid addresses (showing first 1 nodes, use getAllErrors() for more): Node (endPoint=/[240b:cOe0:102:xxxx:xxxx:x:x:x]:3xxx,hostId-null,hashCode=4e9ba6a8):[com.datastax.oss.driver.api.core.connection.ConnectionInitException:[s0|controllid:0x984419ed,L:/[240b:cOe0:102:5dd7: xxxx:x:x:xxx]:4xxx - R:/[240b:c0e0:102:xxxx:xxxx:x:x:x]:3xxx] Protocol initialization request, step 1 (OPTIONS: unexpected tarlure com.datastax.oss.driver.apt.core.connection.closedconnectiontxception: Lost connection to remote peer)]
Network
You appear to have a networking issue. The driver can't connect to any of the nodes because they are unreachable from a network perspective as it states in the error message:
... AllNodesFailedException: Could not reach any contact point ...
You need to check that:
you have configured the correct IP addresses,
you have configured the correct CQL port, and
there is network connectivity between your app and the cluster.
Security
I also noted that you configured the driver to use SSL:
ssl: true
but I don't see anywhere where you've configured the certificate credentials and this could explain why the driver can't initiate connections.
Check that the cluster has client-to-node encryption enabled. If it does then you need to prepare the client certificates and configure SSL on the driver.
Driver build
This post appears to be a duplicate of another question you posted but is now closed due to lack of clarity and details.
In that question it appears you are running a version of the Java driver not produced by DataStax as pointed out by #absurdface:
Specifically I note that java-driver-core-4.11.4-yb-1-RC1.jar isn't a Java driver artifact released by DataStax (there isn't even a 4.11.4 Java driver release). This could be relevant for reasons we'll get into ...
We are not aware of where this build came from and without knowing much about it, it could be the reason you are not able to connect to the cluster.
We recommend that you switch to one of the supported builds of the Java driver. Cheers!
A hearty +1 to everything #erick-ramirez mentioned above. I would also expand on his answers with an observation or two.
Normally spring-data-cassandra is used to automatically configure a CqlSession and make it available for injection (or for use in CqlTemplate etc.). That's what you'd normally be configuring with your application.yml file. But you're apparently creating the CqlSession directly in code, which means that spring-data-cassandra isn't involved... and therefore what's in your application.yml likely isn't being used.
This analysis strongly suggests that your CqlSession is not being configured to use SSL. My understanding is that your testing sequence went as follows:
Tested app locally on a local server, everything worked
Tested app against test environment, observed the errors above
If this sequence is correct and you have SSL enabled in you test environment but not on your local Cassandra instance that could very easily explain the behaviour you're describing.
This explanation could also explain the specific error you cite in the error message. "Lost connection to remote peer" indicates that something is unexpectedly killing your socket connection before any protocol messages are explained... and an SSL issue would cause almost exactly that behaviour.
I would recommend checking the SSL configuration for both servers involved in your testing. I would also suggest consulting the SSL-related documentation referenced by Erick above and confirm that you have all the relevant materials when building your CqlSession.
added the certificate in my spring application
public CqlSession session() throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
Resource resource = new ClassPathResource("root.crt");
InputStream inputStream = resource.getInputStream();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert = cf.generateCertificate(inputStream);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
keyStore.setCertificateEntry("ca", cert);
trustManagerFactory.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
return CqlSession.builder()
.withSslContext(sslContext)
.addContactPoint(new InetSocketAddress(contactPoints,port))
.withAuthCredentials(username, password)
.withLocalDatacenter(localDatacenter)
.withKeyspace(keyspace)
.build();
}
so added the cert file in the configuration file of the cqlsession builder and this helped me in connecting to the remote cassandra cluster

Not able to connect to Cassandra from my spring boot application , throwing exception as couldn't reach any contact-point [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 20 days ago.
Improve this question
added config file to take contact-point programatically
#Bean(destroyMethod = "close")
public CqlSession session() {
CqlSession session = CqlSession.builder()
.addContactPoint(InetSocketAddress.createUnresolved("[240b:c0e0:1xx:xxx8:xxxx:x:x:x]", port))
.withConfigLoader(
DriverConfigLoader.programmaticBuilder()
.withString(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER, localDatacenter) .withString(DefaultDriverOption.AUTH_PROVIDER_USER_NAME,username)
.withString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD,password)
.withString(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT,"10s")
.withString(DefaultDriverOption.CONNECTION_CONNECT_TIMEOUT, "20s")
.withString(DefaultDriverOption.REQUEST_TIMEOUT, "20s")
.withString(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, "20s")
.withString(DefaultDriverOption.SESSION_KEYSPACE,keyspace)
.build())
//.addContactPoint(InetSocketAddress.createUnresolved(InetAddress.getByName(contactPoints).getHostName(), port))
.build();
}
return session;
`Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.datastax.oss.driver.api.core.CqlSession]: Factory method 'cassandraSession' threw exception with message: Since you provided explicit contact points, the local DC must be explicitly set (see basic.load-balancing-policy.local-datacenter in the config, or set it programmatically with SessionBuilder.withLocalDatacenter). Current contact points are: Node(endPoint=/127.0.0.1:9042, hostId=0323221f-9a0f-ec92-ea4a-c1472c2a8b94, hashCode=39075b16)=datacenter1. Current DCs in this cluster are: datacenter1
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:171) ~[spring-beans-6.0.2.jar:6.0.2]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:648) ~[spring-beans-6.0.2.jar:6.0.2]
... 89 common frames omitted
Caused by: java.lang.IllegalStateException: Since you provided explicit contact points, the local DC must be explicitly set (see basic.load-balancing-policy.local-datacenter in the config, or set it programmatically with SessionBuilder.withLocalDatacenter). Current contact points are: Node(endPoint=/127.0.0.1:9042, hostId=0323221f-9a0f-ec92-ea4a-c1472c2a8b94, hashCode=39075b16)=datacenter1. Current DCs in this cluster are: datacenter1
at com.datastax.oss.driver.internal.core.loadbalancing.helper.MandatoryLocalDcHelper.discoverLocalDc(MandatoryLocalDcHelper.java:91) ~[java-driver-core-4.11.4-yb-1-RC1.jar:na]
at com.datastax.oss.driver.internal.core.loadbalancing.DefaultLoadBalancingPolicy.discoverLocalDc(DefaultLoadBalancingPolicy.java:119) ~[java-driver-core-4.11.4-yb-1-RC1.jar:na]
at
this is the application.yml file
spring:
data:
cassandra:
keyspace-name: xxx
contact-points: [xxxx:xxxx:xxxx:xxx:xxx:xxx]
port: xxx
local-datacenter: xxxx
use-dc-aware: true
username: xxxxx
password: xxxxx
ssl: true
SchemaAction: CREATE_IF_NOT_EXISTS
but still the application is pointing towards the localhost , even though i've explicitly mentioned the contact-points and localDC
logs of stg evn are :
caused by: com.datastax.oss.driver.api.core.AllNodesFailedException: Could not reach any contact point, make sure you've provided valid addresses (showing first 1 nodes, use getAllErrors() for more): Node (endPoint=/[240b:cOe0:102:xxxx:xxxx:x:x:x]:3xxx,hostId-null,hashCode=4e9ba6a8):[com.datastax.oss.driver.api.core.connection.ConnectionInitException:[s0|controllid:0x984419ed,L:/[240b:cOe0:102:5dd7:
xxxx:x:x:xxx]:4xxx - R:/[240b:c0e0:102:xxxx:xxxx:x:x:x]:3xxx] Protocol initialization request,
step 1 (OPTIONS: unexpected tarlure com.datastax.oss.driver.apt.core.connection.closedconnectiontxception:
Lost connection to remote peer)]
thanks for the question!
I'll try to provide some pointers that might help you identify the problem but it should be noted that you appear to have some non-standard elements to your application. Specifically I note that "java-driver-core-4.11.4-yb-1-RC1.jar" isn't a Java driver artifact released by DataStax (there isn't even a 4.11.4 Java driver release). This could be relevant for reasons we'll get into in a moment. I also don't recognize the configuration file you cite above. Could you provide some more detail on how your app is configured? At first blush it looked as though you might be using spring-data-cassandra but there wasn't any mention of it in your stack trace... so perhaps you're using some kind of custom configuration code?
As to your specific question: my guess is that you might have a Java driver configuration file in your staging environment which is providing a default value for "datastax-java-driver.basic.contact-points". The 4.x Java driver is configured via the Lightbend Config library. Most relevant to our case it searches for a set of configuration files with various default names on the classpath; these files are then merged together to generate the config passed to the driver. So if you have an application.conf in staging which specifies some contact points and is in the classpath the code you cite above would run fine in your local environment but fail in staging.
To validate this, create an application.conf file in your local environment in src/main/resources (or somewhere else that's explicitly included in the classpath) and give it the following contents:
datastax-java-driver {
basic {
contact-points: ["127.0.0.1:9042"]
}
}
If you then re-run the app in your local environment you should see the error there as well.
Note that the core Java driver JAR already includes a reference.conf file which serves as a default configuration. Here's where the part about a custom JAR figures in; because your not using a standard DataStax Java driver JAR I don't know if you're using the standard reference.conf file defined within that JAR. It's possible that the contact points are defined in that file, although if that were the case I'd expect you to already be seeing the error in any environment where you use that JAR.
One final note: the Java driver should be fine with IPv6 addresses. The issue described above isn't related to IPv6; it's entirely a function of how you're using the Java driver's configuration mechanism.
Hopefully some of the above is helpful!

Connection to Entity Framework works locally, Was working in Azure but now I get "Invalid object name..."

I have looked through various posts related to this problem, but none provide an answer. I created a .Net 5.0 app that accesses an Azure SQL DB using EF 6.4.4 which works with .Net standard libraries. I modified the EF by adding a function that creates the connection string from appsettings.json since .Net 5 apps don't use a web.config file. This also works well in Azure with the configuration settings in an app service.
The connection string looks like this:
metadata=res://*/EF.myDB.csdl|res://*/EF.myDB.ssdl|res://*/EF.myDB.msl;provider=System.Data.SqlClient;provider connection string='Data Source=tcp:mydb.database.windows.net,1433;Initial Catalog=myDB;Integrated Security=False;Persist Security Info=False;User ID=myuserid#mydb;Password="password";MultipleActiveResultSets=True;Connect Timeout=120;Encrypt=True;TrustServerCertificate=True'
I also have a deployment pipeline that will deploy the code after a check-in instead of using the Visual Studio publish feature, but the pipeline deployed code has the same problem.
When I first created the app and published it to the app service, it worked. Recently I updated the app with no changes to the EF connection. Now I get the "Invalid Object name when I reference any table in the model. If I run the same code locally and connect to the Azure SQL DB, the DB is accessed as expected. This problem only occurs when running in the Azure app service. Note that there are no connection strings configured for the app service since the EF string is built from the config settings. I saw this post, but I don't think it applies:
Local works. Azure give error: Invalid object name 'dbo.AspNetUsers'. Why?
even though the problem is the same. I have also read various posts about the format of the EF connection string. Since my model is database first, (and the connection used to work), I'm confident the string has the correct format. I don't think the problem is in the code since it works when running locally with a connection to the Azure SQL DB. It must have something to do with the Azure app service configuration, but I'm not sure what to look for at this point. Unfortunately I don't have a copy of the code and publish files that did work to compare to, but it the pipeline build doesn't work either and that it how the code would normally be deployed. Thanks for any insight you might have!
UPDATE
metadata=res://*/EF.myDB.csdl|res://*/EF.myDB.ssdl|res://*/EF.myDB.msl;provider=System.Data.SqlClient;provider connection string='Data Source=tcp:yourdbsqlserver.database.windows.net,1433;Initial Catalog=yourdb;Persist Security Info=False;User ID=userid;Password=your_password;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30'
When the troubleshooting problem is not on the string, our easiest way is to use vs2019 to re-use the generated string.
Your connection string should be like below.
<connectionStrings>
<add name="SchoolDBEntities" connectionString="metadata=res://*/SchoolDB.csdl|res://*/SchoolDB.ssdl|res://*/SchoolDB.msl;provider=System.Data.SqlClient;provider connection string="data source=.\sqlexpress;initial catalog=SchoolDB;integrated security=True;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient"/>
</connectionStrings>
For more details, you can refer my answer in the post and the tutorial.
1. Timeout period elasped prior to obtaining a connection from the pool - Entity Framework
2. Entity Framework Tutorial
The problem was one of my config settings in Azure. The catalog parameter was missing. A simple fix, but the error message was misleading, so I thought I would note that here in case anyone else gets the same "Invalid object name" message when referencing an Azure SQL DB with EF. It would have been more helpful if the message was "catalog name invalid" or "unable to connect to database".
For those who are curious about building an EF connection string, here is example code:
public string BuildEFConnectionString(SqlConnectionStringModel sqlModel, EntityConnectionStringModel entityModel)
{
SqlConnectionStringBuilder sqlString = new SqlConnectionStringBuilder()
{
DataSource = sqlModel.DataSource,
InitialCatalog = sqlModel.InitialCatalog,
PersistSecurityInfo = sqlModel.PersistSecurityInfo,
UserID = sqlModel.UserID, // Blank if using Windows authentication
Password = sqlModel.Password, // Blank if using Windows authentication
MultipleActiveResultSets = sqlModel.MultipleActiveResultSets,
Encrypt = sqlModel.Encrypt,
TrustServerCertificate = sqlModel.TrustServerCertificate,
IntegratedSecurity = sqlModel.IntegratedSecurity,
ConnectTimeout = sqlModel.ConnectTimeout
};
//Build an Entity Framework connection string
EntityConnectionStringBuilder entityString = new EntityConnectionStringBuilder()
{
Provider = entityModel.Provider, // "System.Data.SqlClient",
Metadata = entityModel.Metadata,
ProviderConnectionString = sqlString.ToString()
};
return entityString.ConnectionString;
}
Given what I have learned, the properties should be validated before the string is returned. If the string is created this way, all of the connection string properties can be added to the config settings in the app service. I used the options pattern to get them at runtime. Thanks to everyone for your suggestions.

CqlSession cannot connect to Azure Cosmos DB Cassandra

I have this code
#Bean
public CqlSession getCqlSession() {
return CqlSession.builder()
.addContactPoint(new InetSocketAddress(cassandraHost, cassandraPort))
.withAuthCredentials(cassandraUsername, cassandraPassword)
.build();
}
The connection is failing with this exception:
Failed to instantiate [com.datastax.oss.driver.api.core.CqlSession]: Factory method 'getCqlSession' threw
exception; nested exception is com.datastax.oss.driver.api.core.AllNodesFailedException: Could not reach
any contact point, make sure you've provided valid addresses (showing first 1 nodes, use getAllErrors()
for more): Node(endPoint=tinyurl-cassandra.cassandra.cosmos.azure.com/52.230.23.170:10350, hostId=null,
hashCode=237f706): [com.datastax.oss.driver.api.core.DriverTimeoutException: [s0|control|id: 0xb89dacff,
L:/192.168.0.101:59158 - R:tinyurl-cassandra.cassandra.cosmos.azure.com/52.230.23.170:10350] Protocol
initialization request, step 1 (OPTIONS): timed out after 5000 ms]
I am new to Cassandra and have tried the following:
Validated that the credentials are okay.
Try with csqlsh - could not connect as well.
Check there's no firewall setup in my machine. Can telnet to host and port.
Can open Cassandra Shell from Azure Data Explorer.
What am I missing? I am new to this. Any help will be appreciated.
Looks like you are using the v.4x version of the Java Driver. The default load balancing in this driver mandates that you provide local data center, e.g:
CqlSession.builder().withSslContext(sc)
.addContactPoint(new InetSocketAddress(cassandraHost, cassandraPort)).**withLocalDatacenter("UK South")**
.withAuthCredentials(cassandraUsername, cassandraPassword).build();
You could take a look at this getting started sample for further reference: https://github.com/Azure-Samples/azure-cosmos-db-cassandra-java-getting-started-v4

Error connecting to Redis on .net Core app hosted on Azure

We have a redis cache hosted on Azure and we use the following as a service in our .net core application:
services.AddSingleton<IConnectionMultiplexer>(provider =>
ConnectionMultiplexer.Connect(Configuration.GetConnectionString("RedisConnection"))
);
Our connection string is similar to the following:
ourserver.redis.cache.windows.net:6380,password=******=,ssl=True,abortConnect=False,syncTimeout=4000
in getting from cache we don't face problems but if we add to cache we sometimes get the following error:
"StackExchange.Redis.RedisConnectionException: It was not possible to
connect to the redis server(s); to create a disconnected multiplexer,
disable AbortOnConnectFail. ConnectTimeout"
I have read solutions like setting abortconnect to false and increasing the timeout but I have implemented it like the connection string above.
If you have suggestions or you think that we have a problem with the connection string kindly advise.
Update: we have implemented a solution to solve connectivity issue but now we get this:
StackExchange.Redis.RedisConnectionException: No connection is available to service this operation
What is your connectTimeout set to? Can you try increasing that to see if it helps?

Resources