How can I connect to my Datastax Cassandra database?

595 views Asked by At

hope all is well with you. I'm currently working with a cassandra database and I'm almost done with it. Currently I am deploying my services and an error occurred. To work best with cassandra in my nestjs back-end I use the framework https://github.com/ifaim/nestjs-express-cassandra This works in the backend with the framework https://github.com/masumsoft/express-cassandra (which is actively updated and used a lot). But now the problem is that according to the documentation of datastax (where my cassandra db is hosted) I have to deposit a secureConnectBundle to be able to connect to my database.

My config

Console Error

Running Database

Example from Datastax

DataStax

However, I have found very little online about this and generally I find more examples of how to connect to your datastax database without secureConnectBundle than with. So far with me but without success and therefore I ask here. I really hope that I do not have to change the framework because that would probably mean the end of this project.

 export const cassandraOptions: ExpressCassandraModuleOptions = {
  clientOptions: {
    contactPoints: [
      'e68eb980-c5c3-47fa-a423-472652519805-europe-west1.db.astra.datastax.com',
    ],
    protocolOptions: { port: 9042 },
    keyspace: 'partii',
    queryOptions: {
      fetchSize: 100,
      consistency: 1,
    },
    authProvider: new auth.PlainTextAuthProvider('X', 'X'),
  },
  ormOptions: {
    createKeyspace: false,
    defaultReplicationStrategy: {
      class: 'SimpleStrategy',
      replication_factor: 1,
    },
    migration: 'safe',
  },
};
4

There are 4 answers

1
Shift On BEST ANSWER

Its solved.

import {
  auth,
  ExpressCassandraModuleOptions,
} from '@iaminfinity/express-cassandra';
// get fs to read the certificate
import * as fs from 'fs';
// get path to resolve the certificate path
import * as path from 'path';

export const cassandraOptions: () => ExpressCassandraModuleOptions = () => {
  const sslOptions = {
    rejectUnauthorized: true,
    cert: fs.readFileSync(path.resolve(__dirname, '../src/database/cert')),
    key: fs.readFileSync(path.resolve(__dirname, '../src/database/key.pem')),
    ca: fs.readFileSync(path.resolve(__dirname, '../src/database/ca.crt')),
  };

  return {
    clientOptions: {
      contactPoints: [
        'host',
      ],
      protocolOptions: { port: 29042 },
      keyspace: 'partii',
      queryOptions: {
        fetchSize: 100,
        consistency: 1,
      },
      sslOptions: {
        ...sslOptions,
        host: '34.79.236.16',
        checkServerIdentity: function (host, cert) {
          return undefined;
        },
      },
      authProvider: new auth.PlainTextAuthProvider(
        'id',
        'secret',
      ),
    },
    ormOptions: {
      createKeyspace: false,
      defaultReplicationStrategy: {
        class: 'SimpleStrategy',
        replication_factor: 1,
      },
      migration: 'alter',
    },
  };
};
3
Madhavan On

You can only create a keyspace via the DevOps API or via the GUI. You may want to follow the examples provided here.

2
Aaron On

You appear to be using DataStax Astra DB. DataStax Astra DB does not connect on the Cassandra default 9042 port, but rather on 29042. However, even with that correct, you'll still have to pass along the SSL info, which is tricky to get correct manually. That's why the recommendation of referencing the secure connect bundle is the easy path.

You're right in that there don't appear to be any examples of using Astra DB with Express Cassandra. The good news, is that Express Cassandra looks like it uses the Cassandra nodejs driver underneath. That means that the client options are likely to be the same/similar. Try something like this:

export const cassandraOptions: ExpressCassandraModuleOptions = {
  clientOptions: {
    cloud: { secureConnectBundle: 'path/to/secure-connect-bundle.zip' },
    credentials: { username: 'clientid', password: 'secret' }
 },
 ormOptions: {
   createKeyspace: false,
   defaultReplicationStrategy: {
     class: 'SimpleStrategy',
     replication_factor: 1,
   },
   migration: 'safe',
 },
};

And if that doesn't work, maybe swap out the credentials line with authProvider you're using above.

1
Shift On

In the meantime I decided to set up the ssl connection manually and it works. Now I just have to fix the error.

apollo.model.tablecreation.dbschemaquery: Error while retrieveing Schema of DB Table "NoHostAvailableError: All host(s) tried for query failed. First host tried, 34.79.132.94:29080: Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altna mes: IP: 34.79.132.94 is not in the cert's list: . See innerErrors.

Implemented files from secure bundle by myself