DataStax Academy FAQ

DataStax Academy migrated to a new learning management system (LMS) in July 2020. We are also moving to a new Cassandra Certification process so there are changes to exam bookings, voucher system and issuing of certificates.

Check out the Academy FAQ pages for answers to your questions:


question

the_a_man avatar image
the_a_man asked ·

How do I connect to Astra with the gocql driver?

I've tried with this sample code but it's not working:

func sessionForRemote() (*gocql.Session, error) {
    log.Println("Connecting to the database")

    config := gocql.NewCluster("14043648-xxxx-469a-a1e0-8331f2739475-us-east1.db.astra.datastax.com") //from bundle's config.json

    config.Authenticator = gocql.PasswordAuthenticator{
        Username: "frameapp",
        Password: "db_password_here",
    }

    certPath, _ := filepath.Abs("./secure-connect-frame-db/cert") //extracted bundle
    caPath, _ := filepath.Abs("./secure-connect-frame-db/ca.crt")
    keyPath, _ := filepath.Abs("./secure-connect-frame-db/key")

    config.SslOpts = &gocql.SslOptions{
        CertPath: certPath,
        CaPath: caPath,
        KeyPath: keyPath,
    }

    config.ConnectTimeout = time.Second * 6
    config.ProtoVersion = 4 //Have tried all (0, 1, 2, 3, 4), to no avail!
    //config.CQLVersion = "3.0.0"
    config.Port = 30431 //From the bundle's config.json (it isn't 9042, rather 30xxx)

    config.Keyspace = "frame_ks"

    fmt.Println("Creating session")
    session, err := config.CreateSession()
    fmt.Println("That's all!")

    if err != nil {
        return nil, err
    }

    return session, nil
}

Output:

Connecting to the database
Creating session
2020/05/01 02:53:29 gocql: unable to dial control conn 34.74.218.22: gocql: unsupported protocol response version: 72
2020/05/01 02:53:34 gocql: unable to dial control conn 35.196.48.167: gocql: unsupported protocol response version: 72
2020/05/01 02:53:39 gocql: unable to dial control conn 35.196.198.226: gocql: unsupported protocol response version: 72

That's all

So it did discover the 3 nodes and passed auth too. It's just this protocol 72 that's annoying!!!!

On the remote, cqlsh'ing

$ show version
[cqlsh 6.8.0 | DSE 6.8.0 | CQL spec 3.4.5 | DSE protocol v2]

I hope you guys come up with some workaround soon... Our whole system is in Go and we can't afford to migrate to python just to be able to connect to Astra! And Astra was such a blessing for a small team of ours that we really don't want to setup DSE on GCP ourselves!

astragcpgogocqlgolang
10 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

1 Answer

Erick Ramirez avatar image
Erick Ramirez answered ·

@the_a_man Thanks for working through this with me. Here is the bare-bones minimum sample code that will let you connect to your DataStax Astra database:

package main

import (
    "fmt"
    "crypto/tls"
    "crypto/x509"
    "io/ioutil"
    "path/filepath"
    "github.com/gocql/gocql"
)

func main() {
    var _cqlshrc_host = "31fecf38-2491-4d43-b6ce-22562679f1b8-us-east1.db.astra.datastax.com"
    var _cqlshrc_port = "34567"
    var _username = "erickramirez"
    var _password = "SomeComp7exP4ssword"
    var _query = "SELECT rank, city, country FROM community.cities_by_rank WHERE rank IN ( 1, 2, 3, 4, 5 )"

    cluster := gocql.NewCluster(_cqlshrc_host)
    cluster.Authenticator = gocql.PasswordAuthenticator{
        Username:       _username,
        Password:       _password,
    }
    cluster.Hosts = []string{_cqlshrc_host + ":" + _cqlshrc_port }

    certPath, _ := filepath.Abs("/home/erick/astra-bundle/cert")
    keyPath, _ := filepath.Abs("/home/erick/astra-bundle/key")
    caPath, _ := filepath.Abs("/home/erick/astra-bundle/ca.crt")
    cert, _ := tls.LoadX509KeyPair(certPath, keyPath)
    caCert, _  := ioutil.ReadFile(caPath)
    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)
    tlsConfig := &tls.Config{
        Certificates: []tls.Certificate{cert},
        RootCAs:      caCertPool,
    }
    cluster.SslOpts = &gocql.SslOptions{
        Config: tlsConfig,
        EnableHostVerification: false,
    }

    session, _ := cluster.CreateSession()
    var _rank int
    var _city string
    var _country string

    fmt.Println("According to independent.co.uk, the top 5 most liveable cities in 2019 were:")
    iter := session.Query(_query).Iter()
    for iter.Scan(&_rank, &_city, &_country) {
        fmt.Printf("\tRank %d: %s, %s\n", _rank, _city, _country)
    }
}

Sample output

According to independent.co.uk, the top 5 most liveable cities in 2019 were:
    Rank 1: Vienna, Austria
    Rank 2: Melbourne, Australia
    Rank 3: Sydney, Australia
    Rank 4: Osaka, Japan
    Rank 5: Calgary, Canada

Things to note

I've deliberately not coded any error-handling as I wanted to provide a minimum viable sample. I've also intentionally not placed any in-line comments but tried to be as descriptive as possible with the variable names for brevity.

For developers wanting to re-use the code above, you will need to download the secure-connect zipped bundle for your Astra database.

Unzip your copy of secure-connect-your_astra_db.zip which will contain the following files:

ca.crt
cert
cert.pfx
config.json
cqlshrc
identity.jks
key
trustStore.jks

You will need these files to configure the SSL/TLS options. The cqlshrc file contains the connection details for _cqlshrc_host and _cqlshrc_port in the code above. For example:

[connection]
hostname = 31fecf38-2491-4d43-b6ce-22562679f1b8-us-east1.db.astra.datastax.com
port = 34567
ssl = true

Sample data

Here is the test schema I used:

CREATE KEYSPACE community WITH replication = {'class': 'NetworkTopologyStrategy', 'caas-dc': '1'};
CREATE TABLE community.cities_by_rank (
    rank int PRIMARY KEY,
    city text,
    country text
)

The table contents:

 rank | city       | country
------+------------+-----------
    5 |    Calgary |    Canada
   10 |   Adelaide | Australia
    1 |     Vienna |   Austria
    8 |      Tokyo |     Japan
    2 |  Melbourne | Australia
    4 |      Osaka |     Japan
    7 |    Toronto |    Canada
    6 |  Vancouver |    Canada
    9 | Copenhagen |   Denmark
    3 |     Sydney | Australia

Source: "This is the world's most liveable city", independent.co.uk, published 4 September 2019, retrieved 2 May 2020.

Github

I've published the full code and sample data for easier download -- https://github.com/flightc/astra_gocql_connect.

Credits

Huge thanks to Doug Wettlaufer at DataStax Cloud Engineering for his help with the solution. Cheers!

10 comments Share
10 |1000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Sure, let me give it a try.

0 Likes 0 · ·

Awesome! You'll see that I've stripped out all the other configs like protocol and CQL versions since they're not required. gocql discovers all that info once it has successfully connected to a node.

It's late Saturday here but I'll be around for a few more hours. Let me know how you go. Cheers!

0 Likes 0 · ·
the_a_man avatar image the_a_man Erick Ramirez ♦♦ ·

Yeah, that's what I noticed. Looks like the ":port" in hosts is all we were missing all this time! No idea why I didn't think about that all this time!

Unparking Astra. Would let you know asap.


0 Likes 0 · ·

I don't think one can create a keyspace on Astra, can one?

Or is the keyspace code just for an explanation?

0 Likes 0 · ·

It's just to show you how I created the sample data. You can use your own keyspace and table.

Not to be taken literally. :) It was just purely for demonstration purposes. Cheers!

0 Likes 0 · ·

Thank you so much! It worked!!!!!!!!!

I was using the port given in the config.json file, rather than the one given in cqlshrc file in the bundle. I sort of avoided the cqlshrc file all this time, thinking it was some "binary-gibberish"!

For anyone reading this:

Use the port from the cqlshrc file.

1 Like 1 · ·

I did mention that in the "Things to note" section of my answer. :)

1 Like 1 · ·
the_a_man avatar image the_a_man Erick Ramirez ♦♦ ·

Yeah, that's where I saw it. Thanks mate, you just saved us days of debugging.

2 Likes 2 · ·
Show more comments