All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.datastax.astra.client.DataAPIClient Maven / Gradle / Ivy

package com.datastax.astra.client;

/*-
 * #%L
 * Data API Java Client
 * --
 * Copyright (C) 2024 DataStax
 * --
 * Licensed under the Apache License, Version 2.0
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import com.datastax.astra.client.admin.AstraDBAdmin;
import com.datastax.astra.client.admin.AstraDBDatabaseAdmin;
import com.datastax.astra.client.admin.DatabaseAdmin;
import com.datastax.astra.internal.api.AstraApiEndpoint;
import com.datastax.astra.internal.utils.Assert;
import com.dtsx.astra.sdk.db.domain.DatabaseCreationBuilder;
import com.dtsx.astra.sdk.utils.AstraEnvironment;

import java.net.http.HttpClient;
import java.util.Optional;
import java.util.UUID;

import static com.datastax.astra.client.DataAPIOptions.DataAPIDestination.ASTRA;
import static com.datastax.astra.client.DataAPIOptions.DataAPIDestination.ASTRA_DEV;
import static com.datastax.astra.client.DataAPIOptions.DataAPIDestination.ASTRA_TEST;
import static com.datastax.astra.client.admin.AstraDBAdmin.DEFAULT_NAMESPACE;

/**
 * Serves as the primary entry point to the Data API client, offering streamlined access to the functionalities
 * provided by the Data API, whether deployed within Astra environments or on-premise DataStax Enterprise installations.
 * 

* This client aims to simplify interactions with the Data API through a user-friendly, high-level API design. It * supports fluent API patterns, builder mechanisms for complex configurations, and employs idiomatic method naming * conventions to enhance readability and ease of use. The design philosophy of this client closely mirrors that of * the established MongoDB API, providing a familiar experience to developers accustomed to MongoDB's client interface. *

*

* Through this client, users can perform a wide range of operations, from basic data manipulation in databases and * collections to more advanced administrative tasks. Administrative capabilities, such as database creation and * namespace management, are available to users with the appropriate administrative privileges. *

* *

Example usage:

*
 * {@code
 * // Initialize the client with default settings
 * DataAPIClient client = new DataAPIClient("yourAuthTokenHere");
 *
 * // Initialize the client with custom HTTP configuration
 * DataAPIClient clientWithCustomConfig = new DataAPIClient("yourAuthTokenHere", DataAPIOptions.builder()
 *                 .withHttpRequestTimeout(1000) // Request timeout in milliseconds
 *                 .withHttpConnectTimeout(10) // Connection timeout in milliseconds
 *                 .withHttpVersion(HttpClient.Version.HTTP_2) // HTTP protocol version
 *                 .withDestination("ASTRA") // Target destination, e.g., Astra
 *                 .build());
 * }
 * 
* * This documentation highlights the ease of starting with the DataAPIClient, whether opting for a quick setup with * default configurations or a more tailored approach via detailed HTTP client settings. The examples demonstrate * both the straightforward initialization process and the method to apply fine-grained configurations for developers' * specific needs. */ public class DataAPIClient { /** parameters names. */ private static final String ARG_NAMESPACE = "namespace"; /** parameters names. */ private static final String ARG_OPTIONS = "options"; /** parameters names. */ private static final String ARG_TOKEN = "token"; /** parameters names. */ private static final String ARG_DATABASE_ID = "databaseId"; /** parameters names. */ private static final String ARG_REGION = "region"; /** * The authentication token used as credentials in HTTP requests, specifically as the Authorization bearer token. * This token is crucial for accessing and interacting with Astra environments, where it plays a role in determining * the access level (e.g., Administrator, User) and scope (e.g., Database, Organization) of the bearer. *

* Tokens generated within Astra environments must adhere to a specific format, starting with "AstraCS:..". These tokens * are obtained via the Astra UI during the database creation process and are designed to not expire, ensuring long-term * access. *

*

* In scenarios involving DataStax Enterprise or on-premise deployments, authentication tokens must be acquired through * the authentication endpoint provided by Stargate. For more information on generating and managing tokens in these contexts, * refer to the Stargate authentication documentation: * Stargate Authentication & Authorization. *

* @see Stargate Authentication & Authorization Documentation */ private final String token; /** * Represents the advanced configuration settings for the client, encapsulating various HTTP-related properties. * This includes settings such as the HTTP version, request and connection timeouts, and the user agent among others. *

* Providing an instance of {@code DataAPIOptions} allows for fine-grained control over the HTTP behavior of the client, * enabling customization to fit specific requirements. If an instance is not explicitly provided, the client * defaults to a pre-configured set of options designed for general use. *

** * @see DataAPIOptions for more details on the available configuration parameters and their effects. */ private final DataAPIOptions options; /** * Constructs a {@code DataAPIClient} instance using the specified authentication token. This constructor * initializes the client with default {@link DataAPIOptions} for its configuration. *

* The provided token is used for authenticating HTTP requests made by this client. It is essential for accessing * secured resources. If specific HTTP configurations are required (e.g., custom timeouts, HTTP version), use the * other constructor that accepts both a token and a {@link DataAPIOptions} instance. *

*

* This constructor is suitable for scenarios where default client settings are sufficient and no advanced * configuration is needed. It simplifies the initialization process for quick setup and use. *

* *

Example usage:

*
     * {@code
     * String myAuthToken = "AstraCS:...";
     * DataAPIClient client = new DataAPIClient(myAuthToken);
     * // Now the client is ready to make authenticated requests with default settings
     * }
     * 
* * @param token The authentication token to be used for HTTP requests. This token should follow the format expected * by the server, typically starting with "AstraCS:.." for Astra environments. */ public DataAPIClient(String token) { this(token, DataAPIOptions.builder().build()); } /** * Constructs a {@code DataAPIClient} with specified authentication token and HTTP client configuration options. *

* This constructor allows for the explicit specification of both the authentication token and the advanced * HTTP configuration settings. The authentication token is essential for securing access to the API, while the * {@link DataAPIOptions} object provides granular control over the HTTP client's behavior, including timeouts, * HTTP version, and other properties impacting connectivity and request handling. *

*

* It is recommended to use this constructor when you need to customize the HTTP client beyond the default * configuration, such as setting custom timeouts or specifying a particular HTTP protocol version. The provided * {@code Assert} methods ensure that neither the token nor the options are null or empty, enforcing the presence of * essential configuration details at the time of client initialization. *

* *

Example usage:

*
     * {@code
     * String myAuthToken = "AstraCS:...";
     * DataAPIOptions myOptions = DataAPIOptions.builder()
     *      .withHttpRequestTimeout(1000)
     *      .withHttpConnectTimeout(500)
     *      .withHttpVersion(HttpClient.Version.HTTP_2)
     *      .build();
     *
     * DataAPIClient myClient = new DataAPIClient(myAuthToken, myOptions);
     * // The client is now ready to perform actions with custom configurations.
     * }
     * 
* * @param token The authentication token to be used for securing API access. This token should adhere to the * format required by the API, typically starting with "AstraCS:.." for Astra environments. * @param options The {@link DataAPIOptions} specifying the detailed HTTP client configurations, offering * customization over aspects such as timeouts and protocol versions. * @throws IllegalArgumentException if the token is empty or null, or if the options are null. */ public DataAPIClient(String token, DataAPIOptions options) { Assert.hasLength(token, ARG_TOKEN); Assert.notNull(options, ARG_OPTIONS); this.token = token; this.options = options; } // -------------------------------------------------- // --- Access AstraDBAdmin --- // -------------------------------------------------- /** * Retrieves an administration client specific to Astra deployments. This client is intended for performing * administrative tasks such as creating databases. It requires the use of a token with sufficient privileges. *

* To use this method effectively, the provided authentication token must be associated with a user having * elevated privileges, such as a Database Administrator or Organization Administrator. This ensures that * the client has the necessary permissions to execute administrative operations within the Astra environment. *

*

* The administration client provides a programmatic interface for managing various aspects of the Astra * deployment, enabling tasks such as database creation, user management, and configuration adjustments * without the need for direct interaction with the Astra UI. *

* *

Example usage:

*
     * {@code
     * DataAPIClient apiClient = new DataAPIClient("AstraCS:your_admin_token_here");
     * AstraDBAdmin adminClient = apiClient.getAdmin();
     * // Use adminClient to perform administrative operations, e.g., create a database
     * }
     * 
* * @return An instance of {@link AstraDBAdmin} configured with the current authentication token, ready for * administrative operations. * @throws SecurityException if the current token does not have the necessary administrative privileges. */ public AstraDBAdmin getAdmin() { return getAdmin(this.token); } /** * Retrieves an administration client capable of performing CRUD operations on databases, requiring a token with * advanced privileges. This method is designed for scenarios where administrative access is necessary beyond the * default token capabilities associated with the {@code DataAPIClient}. *

* The provided {@code superUserToken} should be granted sufficient privileges to perform administrative operations, * such as creating, updating, and deleting databases. This typically involves tokens associated with roles like * Database Administrator or Organization Administrator within the Astra environment. *

*

* Utilizing this method allows for direct access to the Astra database's administrative functionalities, enabling * comprehensive management capabilities through the returned {@link AstraDBAdmin} client. This includes but is not * limited to database creation, modification, and deletion. *

* *

Example usage:

*
     * {@code
     * String superUserToken = "AstraCS:super_user_token_here";
     * DataAPIClient apiClient = new DataAPIClient(superUserToken);
     * AstraDBAdmin adminClient = apiClient.getAdmin(superUserToken);
     * // Now you can use adminClient for administrative operations like creating a database
     * }
     * 
* * @param superUserToken A token with elevated privileges, enabling administrative actions within the Astra * environment. This token must be authorized to perform operations such as creating and managing databases. * @return An instance of {@link AstraDBAdmin}, configured for administrative tasks with the provided user token. * @throws SecurityException if the provided {@code superUserToken} lacks the necessary privileges for administrative operations. */ public AstraDBAdmin getAdmin(String superUserToken) { return new AstraDBAdmin(superUserToken, getAstraEnvironment(), options); } /** * Find the Astra Environment from the destination provided in the initial Optional. It will help * shaping the Api endpoint to spawn sub database objects. * * @return * astra environment if found */ private Optional findAstraEnvironment() { if (options.getDestination() != null) { switch (options.getDestination()) { case ASTRA: return Optional.of(AstraEnvironment.PROD); case ASTRA_DEV: return Optional.of(AstraEnvironment.DEV); case ASTRA_TEST: return Optional.of(AstraEnvironment.TEST); } } return Optional.empty(); } /** * Access the Astra environment or throw an error. Some operation like getAdmin would anly work if the options * are set to Astra. If this is not the case a {@link IllegalArgumentException is thrown.} * * @return * current astra environment * @throws IllegalArgumentException * the destination was not set for Astra in initial options. */ private AstraEnvironment getAstraEnvironment() { return findAstraEnvironment() .orElseThrow(() -> new IllegalArgumentException("'destination' should be ASTRA* to use the AstraDBAdmin")); } // -------------------------------------------------- // --- Access Database --- // -------------------------------------------------- /** * Retrieves a client for a specific database, enabling interactions with the Data API. This method allows for * operations such as querying, updating, and managing data within the specified database and namespace. *

* The {@code databaseId} parameter is a unique identifier for the target database. This ID ensures that operations * performed through the returned client are executed against the correct database instance within the Astra * environment or an on-premise DataStax Enterprise setup. *

*

* The {@code namespace} parameter specifies the namespace (often synonymous with "keyspace" in Cassandra terminology) * within the database to which the client will have access. Namespaces are used to organize and isolate data within * the database, providing a layer of abstraction and security. *

* *

Example usage:

*
     * {@code
     * UUID databaseId = UUID.fromString("your-database-uuid-here");
     * String namespace = "your_namespace_here";
     * DataAPIClient apiClient = new DataAPIClient("yourAuthTokenHere");
     * Database databaseClient = apiClient.getDatabase(databaseId, namespace);
     * // Use databaseClient to perform data operations within the specified namespace
     * }
     * 
* * @param databaseId The unique identifier of the database to interact with. * @param namespace The namespace within the specified database to which operations will be scoped. * @return A {@link Database} client configured to interact with the specified database and namespace, allowing for * data manipulation and query operations. */ public Database getDatabase(UUID databaseId, String namespace) { Assert.notNull(databaseId, ARG_DATABASE_ID); Assert.hasLength(namespace, ARG_NAMESPACE); if (options.getDestination() != ASTRA && options.getDestination() != ASTRA_DEV && options.getDestination() != ASTRA_TEST) { throw new IllegalArgumentException("DataAPIOptions.destination " + "should be set to one of ASTRA* " + "to retrieve a database from an id."); } return new Database(new AstraApiEndpoint(databaseId, getAdmin().getDatabaseInfo(databaseId).getRegion(), getAstraEnvironment()).getApiEndPoint(), this.token, namespace, options); } /** * Retrieves a client for a specific database, enabling interactions with the Data API. This method allows for * operations such as querying, updating, and managing data within the specified database and namespace. * * @param databaseId The unique identifier of the database to interact with. * @param namespace The namespace associated to this database * @param region The cloud provider region where the database is deployed. * * @return * A {@link Database} client configured to interact with the specified database and namespace, allowing for * data manipulation and query operations. */ public Database getDatabase(UUID databaseId, String namespace, String region) { Assert.notNull(databaseId, ARG_DATABASE_ID); Assert.hasLength(namespace, ARG_NAMESPACE); Assert.hasLength(region, ARG_REGION); return new Database(new AstraApiEndpoint(databaseId, region, getAstraEnvironment()).getApiEndPoint(), this.token, namespace, options); } /** * Retrieves a client for interacting with a specified database using its unique identifier. This client facilitates * direct communication with the Data API, enabling a range of operations such as querying, inserting, updating, and * deleting data within the database. This streamlined method provides access to the default namespace or keyspace. *

* The {@code databaseId} serves as a unique identifier for the database within the Astra environment or an on-premise * DataStax Enterprise setup, ensuring that all operations through the client are correctly routed to the intended * database instance. *

* *

Example usage:

*
     * {@code
     * UUID databaseId = UUID.fromString("123e4567-e89b-12d3-a456-426614174000");
     * DataAPIClient apiClient = new DataAPIClient("yourAuthTokenHere");
     * Database databaseClient = apiClient.getDatabase(databaseId);
     * // Perform data operations using the databaseClient
     * }
     * 
* * @param databaseId The unique identifier of the database for which to retrieve the client. * @return A {@link Database} client that provides the ability to perform operations on the specified database. */ public Database getDatabase(UUID databaseId) { return getDatabase(databaseId, DEFAULT_NAMESPACE); } /** * Creates and returns a database client configured to interact with the Data API at the specified API endpoint * and within the given namespace. This method facilitates operations such as querying, inserting, updating, and * deleting data by directly communicating with the Data API, allowing for a wide range of data manipulation * tasks in a specified namespace. *

* The {@code apiEndpoint} parameter should be the URL of the API endpoint where the Data API is hosted. This * is typically a fully qualified URL that points to the Astra service or an on-premise DataStax Enterprise * deployment hosting the Data API. *

*

* The {@code namespace} parameter specifies the namespace (or keyspace in Cassandra terms) within the database * that the client will interact with. Namespaces help organize data within the database and provide a way to * isolate and manage access to data. *

* *

Example usage:

*
     * {@code
     * String apiEndpoint = "https://example-astra-data-api.com";
     * String namespace = "my_keyspace";
     * DataAPIClient apiClient = new DataAPIClient("yourAuthTokenHere");
     * Database databaseClient = apiClient.getDatabase(apiEndpoint, namespace);
     * // Now you can use the databaseClient to perform operations within "my_keyspace"
     * }
     * 
* * @param apiEndpoint The URL of the Data API endpoint. This specifies the location of the API the client will connect to. * @param namespace The namespace (or keyspace) within the database that the client will access and perform operations in. * @return A {@link Database} client configured for the specified API endpoint and namespace, enabling data manipulation * and query operations within the targeted namespace. */ public Database getDatabase(String apiEndpoint, String namespace) { return new Database(apiEndpoint, token, namespace, options); } /** * Retrieves a client for interacting with a specified database using its unique identifier. * * @param apiEndpoint * apiEndpoint for the database. * @return * an instance of Database admin */ public DatabaseAdmin getDatabaseAdmin(String apiEndpoint) { return getDatabase(apiEndpoint).getDatabaseAdmin(); } /** * Retrieves a client for interacting with a specified database using its unique identifier. * * @param databaseId * database identifier * @return * the database admin if exists */ public AstraDBDatabaseAdmin getDatabaseAdmin(UUID databaseId) { return (AstraDBDatabaseAdmin) getDatabase(databaseId).getDatabaseAdmin(); } /** * Retrieves a database client configured to interact with the Data API at the specified API endpoint. This method * enables direct communication with the Data API, facilitating a range of data manipulation operations such as querying, * inserting, updating, and deleting data. The client accesses the default namespace or keyspace for operations, unless * otherwise specified through additional configuration. *

* The {@code apiEndpoint} parameter should be the URL of the Data API endpoint you wish to connect to. This URL * points to the location where the Data API is hosted, which could be an Astra cloud service or an on-premise DataStax * Enterprise instance. *

*

* Utilizing this method simplifies the process of connecting to the Data API by focusing on essential configuration, * making it particularly useful for scenarios where detailed namespace management is handled separately or not required. *

* *

Example usage:

*
     * {@code
     * String apiEndpoint = "https://-.apps.astra.datastax.com";
     * DataAPIClient apiClient = new DataAPIClient("yourAuthTokenHere");
     * Database databaseClient = apiClient.getDatabase(apiEndpoint);
     * // The databaseClient is now ready to perform data operations at the specified API endpoint
     * }
     * 
* * @param apiEndpoint The URL of the Data API endpoint to connect to, specifying the API's location. * @return A {@link Database} client tailored for interaction with the Data API at the provided API endpoint, * ready for executing data manipulation tasks. */ public Database getDatabase(String apiEndpoint) { return getDatabase(apiEndpoint, DEFAULT_NAMESPACE); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy