Obtaining a NoSQL handle

Learn how to access tables using Oracle NoSQL Database Drivers. Start developing your application by creating a NoSQL Handle. Use the NoSQLHandle to access the tables and execute all operations.

In your application, create NoSQLHandle which will be your connection to the Oracle NoSQL Database Proxy. Using this NoSQLHandle you could access the Oracle NoSQL Database tables and execute Oracle NoSQL Database operations. To instantiate NoSQLHandle, pass a reference of NoSQLHandleConfig class to the NoSQLHandleFactory.CreateNoSQLHandle method. Provide the Oracle NoSQL Database Proxy URL as a parameterized constructor to instantiate the NoSQLHandleConfig class.

You could configure the proxy in the Oracle NoSQL Database server in either non-secure or secure mode. The NoSQLHandleConfig class allows an application to specify the security configuration information which is to be used by the handle. For non-secure access, create an instance of the StoreAccessTokenProvider class with the no-argument constructor. For secure access, create an instance of the StoreAccessTokenProvider class with the parameterized constructor. Provide the reference of StoreAccessTokenProvider class to the NoSQLHandleConfig class to establish the appropriate connection.

The following is an example of creating NoSQLHandle that connects to a non-secure proxy.
// Service URL of the proxy
String endpoint = "http://localhost:5000";

// Create a default StoreAccessTokenProvider for accessing the proxy
StoreAccessTokenProvider provider = new StoreAccessTokenProvider();

// Create a NoSQLHandleConfig
NoSQLHandleConfig config = new NoSQLHandleConfig(endpoint);

// Setup authorization provider using StoreAccessTokenProvider
config.setAuthorizationProvider(provider);

// Create NoSQLHandle using the information provided in the config
NoSQLHandle handle = NoSQLHandleFactory.createNoSQLHandle(config);
The following is an example of creating NoSQLHandle that connects to a secure proxy.
// Service URL of the secure proxy
String endpoint = "https://localhost:5000";

// Username of kvstore
String userName = "driver_user";

// Password of the driver user
String password = "DriverPass@@123";

//Construct StoreAccessTokenProvider with username and password
StoreAccessTokenProvider provider = 
    new StoreAccessTokenProvider(userName, password.toCharArray());

// Create a NoSQLHandleConfig
NoSQLHandleConfig config = new NoSQLHandleConfig(endpoint);

// Setup authorization provider using StoreAccessTokenProvider
config.setAuthorizationProvider(provider);

// Create NoSQLHandle using the information provided in the config
NoSQLHandle handle = NoSQLHandleFactory.createNoSQLHandle(config);
For secure access, the StoreAccessTokenProvider parameterized constructor takes the following arguments.
  • username is the username of the kvstore.
  • password is the password of the kvstore user.

Note:

The client driver program should include a driver.trust file path in its JVM environment parameter javax.net.ssl.trustStore to make the secure connection work. The driver.trust should be distributed when the proxy is configured and started. This file is to allow the client driver to certify the proxy server's identity to make a secured connection.

User should generate driver.trust file for the java driver to access the secure proxy. See Generating Certificate and Private Key for the Oracle NoSQL Database Proxy in the Security Guide.

Following is an example of adding the driver.trust file to the client program:

java -Djavax.net.ssl.trustStore=driver.trust -cp .:/lib/nosqldriver.jar Example

A handle has memory and network resources associated with it. Therefore, invoke the NoSQLHandle.close method to free up the resources when the application finishes using the handle.

To minimize network activity, and resource allocation and deallocation overheads, it's best to avoid repeated creation and closing of handles. For example, creating and closing a handle around each operation would incur large resource allocation overheads resulting in poor application performance. A handle permits concurrent operations, so a single handle is sufficient to access tables in a multi-threaded application. The creation of multiple handles incurs additional resource overheads without providing any performance benefit.

A handle is created by first creating a borneo.NoSQLHandleConfig instance to configure the communication endpoint, authorization information, as well as default values for handle configuration. borneo.NoSQLHandleConfig represents a connection to the service. Once created it must be closed using the method borneo.NoSQLHandle.close() in order to clean up resources. Handles are thread-safe and intended to be shared.

If running a secure store, a certificate path should be specified through the REQUESTS_CA_BUNDLE environment variable:
$ export
    REQUESTS_CA_BUNDLE=<path-to-certificate>/certificate.pem:$REQUESTS_CA_BUNDLE

In addition, a user identity must be created in the store (separately) that has permission to perform the required operations of the application, such as manipulated tables and data. The identity is used in the borneo.kv.StoreAccessTokenProvider. If the store is not secure, an empty instance of borneo.kv.StoreAccessTokenProvider is used.

An example of acquiring a NoSQL Handle for Oracle NoSQL Database:
from borneo import NoSQLHandle, NoSQLHandleConfig
from borneo.kv import StoreAccessTokenProvider
#
# Assume the proxy is running on localhost:8080
#
endpoint = 'http://localhost:8080'
#
# Assume the proxy is secure and running on localhost:443
#
endpoint = 'https://localhost:443'
#
# Create the AuthorizationProvider for a secure store:
#
ap = StoreAccessTokenProvider(user_name, password)
#
# Create the AuthorizationProvider for a not secure store:
#
ap = StoreAccessTokenProvider()
#
# create a configuration object
#
config = NoSQLHandleConfig(endpoint).set_authorization_provider(ap)

#
# set the certificate path if running a secure store
#
config.set_ssl_ca_certs(<ca_certs>)

#
# create a handle from the configuration object
#
handle = NoSQLHandle(config)

Configure for non-secure on-premise Oracle NoSQL Database

To connect an application to a non-secure NoSQL database, specify the endpoint at which the Proxy server is running, and specify onprem as configuration mode.
cfg:= nosqldb.Config{
    Mode:     "onprem",
    Endpoint: "http://exampleHostServer:8080",
}
client, err:=nosqldb.NewClient(cfg)
...

Configure for secure on-premise Oracle NoSQL Database

To connect an application to a secure NoSQL database, you need to provide user credentials used to authenticate with the server. If the Proxy server is configured with a self-signed certificate or a certificate that is not trusted by the default system CA, you also need to specifiy CertPath and ServerName for the certificate path and server name used to verify server's certificate.
cfg:= nosqldb.Config{
    Mode:     "onprem",
    Endpoint: "https://exampleHostServer",
    Username: "driverUser",
    Password: []byte("ExamplePassword__123"),
    HTTPConfig: httputil.HTTPConfig{
        CertPath: "/path/to/server-certificate",
        ServerName: "exampleHostServer", // should match the CN subject value from the certificate
    },
}
client, err:=nosqldb.NewClient(cfg)

Class NoSQLClient represents the main access point to the service. To create instance of NoSQLClient you need to provide appropriate configuration information. This information is represented by a plain JavaScript object and may be provided to the constructor of NoSQLClient as the object literal. Alternatively, you may choose to store this information in a JSON configuration file and the constructor of NoSQLClient with the path (absolute or relative to the application's current directory) to that file.

Connecting to a Non-Secure Store

To connect to the proxy in non-secure mode, you need to specify communication endpoint.

For example, if using configuration JavaScript object:
const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
const ServiceType = require('oracle-nosqldb').ServiceType;

const client = new NoSQLClient({
    serviceType: ServiceType.KVSTORE,
    endpoint: 'myhost:8080'
});
You may also choose to store the same configuration in a file. Create file config.json with following contents:
{
    "serviceType": "KVSTORE",
    "endpoint": "myhost:8080",
}
Then you may use this file to create NoSQLClient instance:
const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
const client = new NoSQLClient('/path/to/config.json');

Connecting to a Secure Store

To connect to the proxy in secure mode, in addition to communication endpoint, you need to specify user name and password of the driver user. This information is passed in Config#auth object under kvstore property and can be specified in one of the 3 ways shown below.
  • Passing user name and password directly You may choose to specify user name and password directly. This option is less secure because the password is stored in plain text in memory.
    const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
    
    const client = new NoSQLClient({
        endpoint: 'https://myhost:8081',
        auth: {
            kvstore: {
                user: 'John',
                password: johnsPassword
            }
        }
    });
  • Storing credentials in a file:

    You may choose to store credentials in a separate file which is protected by file system permissions. Credentials file should have the following format:
    {
        "user":     "<Driver user name>",
        "password": "<Driver user password>"
    }
    Then you may reference this credentials file as following:
    const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
    
    const client = new NoSQLClient({
        endpoint: 'https://myhost:8081',
        auth: {
            kvstore: {
                credentials: 'path/to/credentials.json'
            }
        }
    });
  • Creating Your Own KVStoreCredentialsProvider:

    You may implement your own credentials provider for secure storage and retrieval of driver credentials as an instance of KVStoreCredentialsProvider interface. The loadCredentials returns a Promise and thus can be implemented as an async function.
    const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
    
    class MyKVStoreCredentialsProvider {
        constructor() {
            // Initialize required state information if needed
        }
    
        async loadCredentials() {
            // Obtain client id, client secret, user name and user password somehow
            return { // Return credentials object as a result
                user: driverUserName,
                password: driverPassword
            };
        }
    }
    let client = new NoSQLClient({
        endpoint: 'https://myhost:8081',
        auth: {
            kvstore: {
                credentials: new MyKVStoreCredentialsProvider(myArgs...)
            }
        }
    });

Class NoSQLClient represents the main access point to the service. To create instance of NoSQLClient you need to provide appropriate configuration information. This information is represented by NoSQLConfig class which instance can be provided to the constructor of NoSQLClient. Alternatively, you may choose to store the configuration information in a JSON configuration file and use the constructor of NoSQLClient that takes the path (absolute or relative to current directory) to that file.

Connecting to a Non-Secure Store

In non-secure mode, the driver communicates with the proxy via the HTTP protocol. The only information required is the communication endpoint. For on-premise NoSQL Database, the endpoint specifies the url of the proxy, in the form http://proxy_host:proxy_http_port. To connect to the proxy in non-secure mode, you need to specify communication endpoint and the service type as ServiceType.KVStore.

You can provide an instance of NoSQLConfig either directly or in a JSON configuration file.
var client = new NoSQLClient(
    new NoSQLConfig
    {
        ServiceType = ServiceType.KVStore,
        Endpoint = "myhost:8080"
    });
You may also choose to provide the same configuration in JSON configuration file. Create file config.json with following contents:
{
    "ServiceType": "KVStore",
    "Endpoint": "myhost:8080"
}
Then you may use this file to create NoSQLClient instance:
varclient = new NoSQLClient("/path/to/config.json");

Connecting to a Secure Store :

To connect to the proxy in secure mode, in addition to communication endpoint, you need to specify user name and password of the driver user. This information is passed in the instance of KVStoreAuthorizationProvider and can be specified in one of the 3 ways shown below.

Passing user name and password directly

You may choose to specify user name and password directly. This option is less secure because the password is stored in plain text in memory for the lifetime of NoSQLClient instance. Note that the password is specified as char[] which allows you to erase it after you are finished using NoSQLClient.

You may choose to store credentials in a separate file which is protected by file system permissions. Credentials file should have the following format:
{
    "user":     "<Driver user name>",
    "password": "<Driver user password>"
}
Then you may use this credentials file as following:
var client = new NoSQLClient(
    new NoSQLConfig
    {
        Endpoint: 'https://myhost:8081',
        AuthorizationProvider=newKVStoreAuthorizationProvider(
            "path/to/credentials.json")
    });
You may implement your own credentials provider for secure storage and retrieval of driver credentials. This is the most secure option because you are in control of how the credentials are stored and loaded by the driver. The credentials provider is a delegate function that returns Task<KVStoreCredentials> and thus may be implemented asynchronously.
var client = new NoSQLClient(
    newNoSQLConfig
    {
        "Endpoint": "https://myhost:8081",
        AuthorizationProvider=newKVStoreAuthorizationProvider(
           async (CancellationToken) => {
                // Retrieve the credentials in a preferred manner.await..........
                returnnewKVStoreCredentials(myUserName, myPassword);
           })
    });

Obtaining a NoSQL connection

In a Spring Data application, you must set up the AppConfig class that provides a NosqlDbConfig Spring bean. The NosqlDbConfig Spring bean describes how to connect to the Oracle NoSQL Database.

Create the AppConfig class that extends the AbstractNosqlConfiguration class. This exposes the connection and security parameters to the Oracle NoSQL Database SDK for Spring Data.

Return a NosqlDbConfig instance object with the connection details to the Oracle NoSQL Database Proxy. Provide the @Configuration and @EnableNoSQLRepositories annotations to this NosqlDbConfig class. The @Configuration annotation informs the Spring Data Framework that the AppConfig class is a configuration class that should be loaded before running the program. The @EnableNoSQLRepositories annotation informs the Spring Data Framework that it needs to load the program and look up for the repositories that extend the NosqlRepository interface. The @Bean annotation is required for the repositories to be instantiated.

Create a nosqlDbConfig @Bean annotated method to return an instance of the NosqlDBConfig class. The NosqlDBConfig instance object will be used by the Spring Data Framework to authenticate the Oracle NoSQL Database.

You can use the StoreAccessTokenProvider class to configure the Spring Data Framework to connect and authenticate with an Oracle NoSQL Database. You need to provide the URL of the Oracle NoSQL Database Proxy with non-secure access. For more details on StoreAccessTokenProvider class, see StoreAccessTokenProvider in the SDK for Spring Data API Reference.
import com.oracle.nosql.spring.data.config.AbstractNosqlConfiguration;
import com.oracle.nosql.spring.data.config.NosqlDbConfig;
import com.oracle.nosql.spring.data.repository.config.EnableNosqlRepositories;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import oracle.nosql.driver.kv.StoreAccessTokenProvider;
 
@Configuration
 
@EnableNosqlRepositories
 
public class AppConfig extends AbstractNosqlConfiguration {
    @Bean
    public NosqlDbConfig nosqlDbConfig() {
        AuthorizationProvider authorizationProvider;
        authorizationProvider = new StoreAccessTokenProvider();
 
        /* Provide the hostname and port number of the NoSQL cluster.*/
        return new NosqlDbConfig("http://<host:port>", authorizationProvider);
    }
}
The following example modifies the previous example to connect to a secure Oracle NoSQL Database store.
import com.oracle.nosql.spring.data.config.AbstractNosqlConfiguration;
import com.oracle.nosql.spring.data.config.NosqlDbConfig;
import com.oracle.nosql.spring.data.repository.config.EnableNosqlRepositories;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import oracle.nosql.driver.kv.StoreAccessTokenProvider;
 
@Configuration
 
@EnableNosqlRepositories
public class AppConfig extends AbstractNosqlConfiguration {
 
    @Bean
    public NosqlDbConfig nosqlDbConfig() {
        AuthorizationProvider authorizationProvider;
        /* Provide the username and password of the NoSQL cluster.*/
        authorizationProvider = new StoreAccessTokenProvider(user, password);
 
        /* Provide the hostname and port number of the NoSQL cluster.*/
        return new NosqlDbConfig("http://<host:port>", authorizationProvider);
    }
}