-
Notifications
You must be signed in to change notification settings - Fork 10
Astra SDK Reference Configuration
This page will cover the different options and configurations available to work with Astra SDK. To get more information regarding one API in particular please refer to the proper chapter in the menu on the left.
In the following tutorial we expect you to already have a database running and a token. If you need to create them have a look to the quickstart
- Architecture
- SDK design principles
- Configuration
AstraClient
- Sample Code
AstraClient
- Load-Balancing and Failover
- Working with
AstraRC
Datastax ASTRA is a the cloud platform of Datastax. It provides AstraDB and Astra Streaming services.
-
AstraDB is a DBAAS (database as a service) for Apache Cassandraβ’. You can start and run instances with a few clicks. The platform provides the databases nodes but also Stargate nodes with the tools to use the apis (swagger and graphQL playground).
-
Astra Streaming is a SAAS (software as a service) for Apache Pulsarβ’. You can create tenants with a few clicks and use all components of the message broker: namespaces, topics, subscriptions, functions....
- One to multiple region(s).
- Each region will have 3 Cassandra nodes, 3 Stargate nodes, the CQL Console, Swagger-UI, GraphQL Playground and the load balancer to distribute the requests across the nodes.
As such, with Astra, there is no need to perform any load balancing at client side. You can eventually perform a failover across astra regions.
Interface | host | protocol | ports | Paths |
---|---|---|---|---|
CqlSession | ${dbid}-${dbregion}.db.astra.datastax.com |
tcp |
29042,29080 |
-- |
Rest Api | ${dbid}-${dbregion}.apps.astra.datastax.com |
http |
443 |
api/rest* |
Doc Api | ${dbid}-${dbregion}.apps.astra.datastax.com |
http |
443 |
api/rest* |
Graph Api | ${dbid}-${dbregion}.apps.astra.datastax.com |
http |
443 |
api/graphql* |
Grpc Api | ${dbid}-${dbregion}.apps.astra.datastax.com |
tcp |
443 |
-- |
Devops Api | https://api.astra.datastax.com |
http |
443 |
/v2* |
Pulsar Client | <clustername>.streaming.datastax.com |
tcp |
6651,8001 |
-- |
Pulsar Admin | <clustername>.api.streaming.datastax.com |
http |
443 |
/* |
The Astra SDK
library leverage on the Stargate SDK. As such it will reuse the same technologies for Cql, Http, gRPC, and graphQL, those are detailed here.
The Astra SDK
adds some Http clients for the Devops Apis (databases, organization, streaming) reusing the same Http Component but also the pulsar-client
and pulsar-admin
needed to interact with Astra Streaming.
-
Users need a single class to setup the SDK, namely
AstraClientConfig
. There will be multiple ways to load the populate this object (builders, yaml) and an extension point is provided for you to create your own. -
Users need a single class to use the SDK, namely
AstraClient
. -
AstraClient
will setup and reuseStargateClient
class. As such the configuration will have a lot of similarities. Yet the Astra configuration is expected to be simpler as load-balancing is handle for us. Also the underlyingStargateClient
should not be hidden to developers.
StargateClient stargateClient = astraClient.getStargateClient();
- Keep it Simple Stupid (KISS). A fluent Api is a great way to guide developers in the usage of the different functions available.
DatabasesClient apiDevopsDatabases = astraClient.apiDevopsDatabases();
OrganizationsClient apiDevopsOrg = astraClient.apiDevopsOrganizations();
StreamingClient apiDevopsStreaming = astraClient.apiDevopsStreaming();
ApiDataClient apiDataRest = astraClient.apiStargateData();
ApiDocumentClient apiDocument = astraClient.apiStargateDocument();
ApiGraphQLClient apiGraphClient = astraClient.apiStargateGraphQL();
ApiGrpcClient apiGrpc = astraClient.apiStargateGrpc();
CqlSession = astraClient.cqlSession();
- Initialize only Api(s) that can be used and disable others with no errors.
com.datastax.astra.sdk.config.AstraClientConfig : Initializing [AstraClient]
com.datastax.astra.sdk.AstraClient : + API(s) Devops [ENABLED]
com.datastax.astra.sdk.AstraClient : + Using db with id [290eb696-c9ed-48b2-ac22-350f71baaee7] and region [us-east-1]
com.datastax.astra.sdk.AstraClient : + Downloading bundles in: [/Users/cedricklunven/.astra]
com.datastax.astra.sdk.databases.DatabaseClient : + SecureBundle found : scb_290eb696-c9ed-48b2-ac22-350f71baaee7_us-east-1.zip
com.datastax.astra.sdk.databases.DatabaseClient : + SecureBundle found : scb_290eb696-c9ed-48b2-ac22-350f71baaee7_eu-central-1.zip
com.datastax.astra.sdk.AstraClient : + Credentials used for Cql 'token' with ${token}
com.datastax.stargate.sdk.StargateClient : Initializing [StargateClient]
com.datastax.stargate.sdk.StargateClient : + Stargate nodes #[1] in [eu-central-1]
com.datastax.stargate.sdk.StargateClient : + Stargate nodes #[1] in [us-east-1]
com.datastax.stargate.sdk.StargateClient : + CqlSession :[ ENABLED ]
com.datastax.stargate.sdk.rest.ApiDataClient : + API Data :[ ENABLED ]
com.datastax.stargate.sdk.doc.ApiDocumentClient : + API Document :[ ENABLED ]
com.datastax.stargate.sdk.gql.ApiGraphQLClient : + API GraphQL :[ ENABLED ]
com.datastax.stargate.sdk.grpc.ApiGrpcClient : + API Grpc :[ ENABLED ]
com.datastax.astra.sdk.AstraClient : [AstraClient has been initialized.
- Simplify user journey. To use the
CqlSession
with Astra you need to provide a zip file with the security certificates. This is file is called theSecure Cloud Bundle
orSCB
. The SDK will use the devops Api to download them for the user and save them by default in~/.astra/scb_dbid_dbregion.zip
.
In the following chapter we will describe the different parameters available for you to build the client class AstraClient
through its builder.
AstraClientConfig astraClientConfig = AstraClient.builder();
In the builder there are 4 ways to retrieve configuration values and they will be loaded in the following order:
1. System Environment variables
2. Override by (if provided) read Java Arguments (-Dxx=yy)
3. Override by (if provided) file `~/.astrarc` with default section
4. Override by (if provided) explicit configuration in the builder (java code)
Not all parameters can be with environment variables (too many) here is the list:
Environment Variable | Definition |
---|---|
ASTRA_DB_ID | Unique identifier for your database |
ASTRA_DB_REGION | Default region used to connect to your database |
ASTRA_DB_CLIENT_ID | Part of the generated tokens, it acts as your username |
ASTRA_DB_CLIENT_SECRET | Part of the generated tokens, it acts as your password |
ASTRA_DB_APPLICATION_TOKEN | Part of the generated tokens, technical token used in Api Headers |
ASTRA_DB_KEYSPACE | Default selected keyspace in Astra |
ASTRA_DB_SCB_FOLDER | Folder where to download the secure connect bundles (one per region) |
Populate application name field in CqlSession.
astraClientConfig.withApplicationName("app_name")
This is your username when interacting with CQL API, it is part of the token generated.
astraClientConfig.withClientId("client_id")
This is your password when interacting with CQL API, it is part of the token generated.
astraClientConfig.withClientSecret("client_secret")
*Each property in application.conf
is identified by a key. Sometimes you want those keys to be set programmatically. Here the OptionsMap
will be updated with this property.
//astraClientConfig.withCqlDriverOption(TypedDriverOption<T>, T);
astraClientConfig.withCqlDriverOption(
TypedDriverOption.CONNECTION_CONNECT_TIMEOUT,
Duration.ofSeconds(10))
Set current keyspace in the cqlSession.
astraClientConfig.withCqlKeyspace("keyspace")
Setup metrics (Dropwizard) at Cql driver level.
astraClientConfig.withCqlMetricsRegistry(myMeterMetricsRegistry)
Setup request tracker at Cql driver level.
astraClientConfig.withCqlRequestTracker(RequestTracker)
Allow programmatic external configuration before creating CqlSession
astraClientConfig.withCqlSessionBuilderCustomizer(CqlSessionBuilderCustomizer)
Required for anything except devops apis, it will identify the database you want to work with
astraClientConfig.withDatabaseId("db_id")
Required for anything except devops apis, it will identify the database you want to work with
astraClientConfig.withDatabaseRegion("db_region")
*Fine tuning HTTP requests with ClientConfiguration (timeouts, keepalive, pooling...). Default are 20
seconds for timeouts.
astraClientConfig.withHttpRequestConfig(RequestConfig.custom()
.setCookieSpec(StandardCookieSpec.STRICT)
.setExpectContinueEnabled(true)
.setConnectionRequestTimeout(Timeout.ofSeconds(5))
.setConnectTimeout(Timeout.ofSeconds(5))
.setTargetPreferredAuthSchemes(Arrays.asList(StandardAuthScheme.NTLM, StandardAuthScheme.DIGEST))
.build())
*Fine tuning for Http retries. But default a call is retried 3 times before the resources is considered unavailable by the internal load balancer. The retries are done in exponential backoff, after 100 millis, 200 millis and 400 millis.
astraClientConfig.withHttpRetryConfig(new RetryConfigBuilder()
.retryOnAnyException()
.withDelayBetweenTries(Duration.ofMillis(100))
.withExponentialBackoff()
.withMaxNumberOfTries(3)
.build();)
Define your observer and get notified for each request and retry. The class should implement ApiInvocationObserver
.
public class SampleHttpObserver implements ApiInvocationObserver {
/** {@inheritDoc} */
@Override
public void onCall(ApiInvocationEvent event) {
System.out.println(event.getHost());
}
/** {@inheritDoc} */
@Override
public void onHttpSuccess(Status<String> s) {}
/** {@inheritDoc} */
@Override
public void onHttpCompletion(Status<String> s) {}
/** {@inheritDoc} */
@Override
public void onHttpFailure(Status<String> s) {}
/** {@inheritDoc} */
@Override
public void onHttpFailedTry(Status<String> s) {}
}
You can register an observer by its name
astraClientConfig.addHttpObserver("sample", new SampleHttpObserver());
You can register all observer by providing a Map
Map<String, ApiInvocationObserver> observers = new HashMap<>();
observers.put("sample", new SampleHttpObserver());
observers.put("log", new AnsiLoggerObserver());
astraClientConfig.withHttpObservers(observers)
2 observers are provided out of the box AnsiLoggerObserver
and AnsiLoggerObserverLight
.
To enforce a stateless client with no usage of the cqlSession you can disable CQL with this flag
astraClientConfig.withoutCqlSession()
Location of the ZIP files required to initialize a connection to Astra.
astraClientConfig.withSecureConnectBundleFolder("/tmp")
Mandatory for any api call except the cql session.
astraClientConfig.withToken("AstraCS:....")
Here is a full fledge initialization of the AstraClient
.
public AstraClient setupAstra() {
return AstraClient.builder()
// Astra Credentials Settings
.withClientId("my_client_id")
.withClientSecret("my_client_secret")
.withToken("my_token")
// Astra DB instance Settings
.withDatabaseId("my_db_id")
.withDatabaseRegion("my_db_region")
// Cql Settings
//.withoutCqlSession()
.withApplicationName("SampleAPP")
.withCqlDriverOption(TypedDriverOption.CONNECTION_CONNECT_TIMEOUT, Duration.ofSeconds(10))
.withCqlDriverOption(TypedDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofSeconds(10))
.withCqlDriverOption(TypedDriverOption.CONNECTION_SET_KEYSPACE_TIMEOUT, Duration.ofSeconds(10))
.withCqlDriverOption(TypedDriverOption.CONTROL_CONNECTION_TIMEOUT, Duration.ofSeconds(10))
.withCqlKeyspace("quickstart")
.withCqlSessionBuilderCustomizer(new CqlSessionBuilderCustomizer() {
/** {@inheritDoc} */
@Override
public void customize(CqlSessionBuilder cqlSessionBuilder) {
cqlSessionBuilder.withClassLoader(null);
}})
.withCqlMetricsRegistry(myMeterMetricsRegistry)
//.withCqlRequestTracker(null)
.withSecureConnectBundleFolder("~/.astra")
// Http Client Settings
.withHttpRequestConfig(RequestConfig.custom()
.setCookieSpec(StandardCookieSpec.STRICT)
.setExpectContinueEnabled(true)
.setConnectionRequestTimeout(Timeout.ofSeconds(5))
.setConnectTimeout(Timeout.ofSeconds(5))
.setTargetPreferredAuthSchemes(Arrays.asList(StandardAuthScheme.NTLM, StandardAuthScheme.DIGEST))
.build())
.withHttpRetryConfig(new RetryConfigBuilder()
.retryOnAnyException()
.withDelayBetweenTries( Duration.ofMillis(100))
.withExponentialBackoff()
.withMaxNumberOfTries(10)
.build())
.addHttpObserver("logger_light", new AnsiLoggerObserver())
.addHttpObserver("logger_full", new AnsiLoggerObserverLight())
.build();
}
With AstraDB you can create multiple datacenters or regions for your instance. Each region will host 3 nodes of Cassandra and 3 nodes of Stargate. In this chapter will we cover design choices regarding Load Balancing and FailOver and how to use them with the SDK.
- AstraDB load-balancing is done for your through Kubernetes Services (ingress), you have nothing to setup. The load balancing is done INSIDE A SINGLE REGION to keep the latencies low. Considering another
It is recommended to perform failover across regions/datacenters at application level with DNS based routing. Indeed if the failover is implemented at data layer we can see some spikes in the latencies (from 25ms to 150 ms in our tests on Astra).
βΉοΈ Code of this demonstration is available for download π₯ here.
To setup the SDK you can provide values using the builder as listed above but not only you can save them locally in some configuration file (.astrarc
).
π (a) Understanding configuration file ~/.astrarc
This file uses the ini
configuration formatting. A key ASTRA_DB_APPLICATION_TOKEN
is associated to its value. Values are grouped in sections identified by a [name]
.
Sample File with 2 sections:
[default]
ASTRA_DB_APPLICATION_TOKEN=AstraCS:GmSdU.....
ASTRA_DB_CLIENT_ID=GmSdUgw....
ASTRA_DB_CLIENT_SECRET=pL7QcZgN....
ASTRA_DB_ID=33a7527a-aaf9-4f9f-9758-96216efff3d5
ASTRA_DB_KEYSPACE=ks1
ASTRA_DB_REGION=eu-central-1
ASTRA_DB_SECURE_BUNDLE=
[sandbox]
ASTRA_DB_APPLICATION_TOKEN=AstraCS:GmSdU.....
ASTRA_DB_CLIENT_ID=GmSdUgw....
ASTRA_DB_CLIENT_SECRET=pL7QcZgN....
ASTRA_DB_ID=33a7527a-aaf9-4f9f-9758-96216efff3d5
ASTRA_DB_KEYSPACE=ks1
ASTRA_DB_REGION=eu-central-1
ASTRA_DB_SECURE_BUNDLE=
The file starts with a [default]
section. If nothing name is provided it will be the one to load. In the SDK this file will be associated with the class com.datastax.astra.sdk.utils.AstraRc
π (b) Generate an ~/.astrarc
// Generate the file in default location user home (~/.astrarc)
AstraRc.create("<your_token>");
// Generate the file in a defined location
AstraRc.create("<your_token>", new File("/tmp/astracrc"));
π (c) Load an ~/.astrarc
file
// Load default file (~/.astrarc)
AstraRc confAstraRc1 = AstraRc.load()
// Load a file in defined location
AstraRc confAstraRc2 = AstraRc.load("/tmp/astracrc");
π (d) Update an ~/.astrarc
file
confAstraRc1.save("sectionName", "keyName", "keyValue");
The SDK can be and will be used in Docker and Kubernetes contextes. For those you provide parameters through environment variables. The SDK is ready for that here is the list of environment variables than you can provide:
Environment Variable | Definition |
---|---|
STARGATE_USERNAME | User identifier to login to Stargate |
STARGATE_PASSWORD | User password to login to Stargate |
STARGATE_ENDPOINT_AUTH | Authentication endpoint to get a Token |
STARGATE_ENDPOINT_REST | Endpoint for Data and Document APIs |
STARGATE_ENDPOINT_GRAPHQL | Endpoint for GraphQL APIs |
STARGATE_ENDPOINT_CQL | Contact Point adresse ip:port |
STARGATE_LOCAL_DC | Local DataCenter name |
STARGATE_KEYSPACE | Keyspace selected |
STARGATE_ENABLE_CQL | Even with user/[assword you can disable CQL to stay stateless |
ASTRA_DB_ID | Astra database identifier |
ASTRA_DB_REGION | Main region for the database |
ASTRA_DB_APPLICATION_TOKEN | Your Token AstraCS:... |
ASTRA_DB_CLIENT_ID | ClientId part of your token |
ASTRA_DB_CLIENT_SECRET | ClientSecret part of your token |
ASTRA_DB_KEYSPACE | Keyspace to use in ASTRA |
ASTRA_DB_SECURE_BUNDLE | Location where to find the secure connect bundle |
The same variables can be provided as Java parameter using the syntax -DKEY=VALUE
java -jar myapp.jar -DSTARGATE_USERNAME=cassandra -DSTARGATE_PASSWORD=cassandra
π Home | Document | Rest | Native Drivers | GraphQL | gRPC | Astra Devops |