This blog covers the programmatic interfaces for deploying Global Active Tables. For the technical overview on Global Active Tables’ architecture, configuration, and operation, please refer to this companion blog. If you are interested in the overview, value propositions, and business use cases, please refer to this blog.

 

Introduction

In an ever-changing global economy, businesses must embrace changes and move fast when new opportunities emerge. Every second counts! Enterprises can’t afford complexity. Your business’s success and survival depend on innovations, solution delivery, and operation measured by speed, efficiency, reliability, and costs.

Imagine the following application data platform deployment catching up with the speed of change. There are moments when deployment starts small but needs to scale out fast and distribute worldwide. There are moments when other opportunities emerge in different regions, and the current deployments must be torn down quickly to build new data platforms in new regions. Enterprises must seize every business opportunity to offer the best digital experience through mobile applications while outpacing the competition. 

Instant Agility

In the companion blog, I show how Global Active Tables unravel the underlying technical complexity and offers absolute simplicity to users. This blog focuses on how Global Active Tables provide instant agility for businesses with a dynamic data platform that can be easily deployed globally, torn down, re-configured, rebuilt, or expanded to meet different scenarios in minutes. Programmatic interfaces enable such dynamic configuration easily, empowering businesses to embrace changes and jump on new opportunities in a snap at the global scale.

Programmatic Interfaces

Global Active Table offers a variety of programmatic interfaces for configuring Global Active Tables in minutes, adapting to the needs of business at the global scale.

  • NoSQL SDKs 
  • OCI Terraform
  • OCI SDKs
  • OCI REST APIs

The following sections show code snippets for different types of interfaces.  Let’s start simply by creating new Global Active Tables in two regions. For complete tutorials on programmatic interfaces, refer to this documentation.

Flow Chart for Configuration Global Active Tables

The process creates a new NoSQL table in local region 1, adds the table replica to a remote region 2, and enables a Global Active Table in two steps. Once configured, all local update operations in either region will be automatically replicated to the other region. 

Configure Global Active Tables

 

Code Snippets for Configuring Global Active Tables

Following are code snippets from different programmatic interfaces to create a Global Active Table in two steps, with region 1 in Ashburn and region 2 in Phoenix.

Embed these snippets in your code or scripts using your preferred programming style and variable names, e.g., compartmentID, tableName, region. The snippets illustrate the provisioned capacity mode for Global Active Tables. The later section covers the on-demand capacity mode. For more details on capacity modes, refer to this page.

Step 1 creates a new singleton table named demoGlobalTable in the Ashburn region.

Step 2 adds a regional table replica in the Phoenix region.

NoSQL SDK (Java)

Following is a Java SDK code snippet to configure a new Global Active Table. 

/* Step 1: Create a singleton table at the Ashburn region */
String ddl = “CREATE TABLE IF NOT EXISTS ” + tableName +
                  “(id INTEGER, personInfo JSON, PRIMARY KEY(id)) ” +
                  “with schema frozen”;
 
TableRequest tableReq = new TableRequest()
            .setStatement(ddl)
            .setTableLimits(new TableLimits(50, 50, 1));
 
TableResult res = handle.tableRequest(tableReq);
        res.waitForCompletion(handle, 90000, 1000);
 
/* Step 2: Add replica at the Phoenix region */
AddReplicaRequest addRepReq = new AddReplicaRequest()
                .setTableName(tableName)
                .setReplicaName(region);
        res = handle.addReplica(addRepReq);
        res.waitForCompletion(handle, 90000, 1000);

OCI Terraform

Following is a Terraform code snippet to configure a new Global Active Table. 

/* Step 1: Create a singleton table at the Ashburn region */
resource “oci_nosql_table” “demoGlobalTable” {
  compartment_id = var.compartment_ocid
  ddl_statement  = “CREATE TABLE IF NOT EXISTS demoGlobalTable(id INTEGER, personInfo JSON, PRIMARY KEY(id)) with schema frozen”
  name = “demoGlobalTable”
 
  table_limits {
    max_read_units     = “50”
    max_write_units    = “50”
    max_storage_in_gbs = “1”
  }
}
 
resource “oci_nosql_table_replica” “ashburn” {
  table_name_or_id = oci_nosql_table.users.id
  region = “us-ashburn-1”
}
 
/* Step 2: Add replica at the Phoenix region */
resource “oci_nosql_table_replica” “phoenix” {
  table_name_or_id = oci_nosql_table.users.id
  region = “us-phoenix-1”
}

OCI SDK (Java)

Following is an OCI SDK  code snippet to configure a new Global Active Table. 

/* Step 1: Create a singleton table at the Ashburn region */
String ddl = “CREATE TABLE IF NOT EXISTS ” + tableName + “(” +
                     “id INTEGER, personInfo JSON, PRIMARY KEY(id)) ” +
                     “with schema frozen”;
     
TableLimits limits = TableLimits.builder()
                          .maxReadUnits(50)
                          .maxWriteUnits(50)
                          .maxStorageInGBs(1)
                          .build();
     
CreateTableDetails.Builder payload = CreateTableDetails.builder()
                          .compartmentId(compartmentId)
                          .name(tableName)
                          .ddlStatement(ddl)
                          .tableLimits(limits);
      
CreateTableRequest tableReq = CreateTableRequest.builder()
                               .createTableDetails(payload.build())
                               .build();
 
CreateTableResponse tableRes = client.createTable(tableReq);
waitForComplete(client, tableRes.getOpcWorkRequestId());
    
 
/* Step 2: Add replica at the Phoenix region */
CreateReplicaDetails info = CreateReplicaDetails
                               .builder()
                               .region(region)
                               .compartmentId(compartmentId)
                               .build();
      
CreateReplicaRequest replicaReq = CreateReplicaRequest
                               .builder()
                               .tableNameOrId(tableName)
                               .createReplicaDetails(info)
                               .build();
  
CreateReplicaResponse replicaRes = client.createReplica(replicaReq);
waitForComplete(client, replicaRes.getOpcWorkRequestId());    

OCI CLI

Following is an OCI CLI code snippet to configure a new Global Active Table. 

#  Step 1: Create a singleton table at the Ashburn region
oci nosql table create \
–endpoint $ENDPOINT \
–compartment-id $COMPARTMENT_ID \
–name mrtest \
–ddl-statement “create table if not exists demoGlobalTable(id integer, info personJson, primary key(id)) with schema frozen” \
–table-limits ‘{“maxReadUnits”: 50, “maxWriteUnits”: 50, “maxStorageInGBs”: 1}’ \
–wait-for-state SUCCEEDED
 
# Step 2: Add replica at the Phoenix region
oci nosql table create-replica \
–endpoint $ENDPOINT \
–compartment-id $COMPARTMENT_ID \
–table-name-or-id demoGlobalTable \
–replica-region us-phoenix-1 \
–wait-for-state SUCCEEDED

 

More Code Snippets for Global Active Tables Operations

The following showcases a few common Global Active Table operations, using the same configuration above. For other interfaces, refer to this documentation

Drop a Table Replica in a Region 

When new business opportunities emerge in different regions, the current Global Active Table must be torn down quickly to deploy new ones in other regions. Before removing the current Global Active Tables all the regional table replicas must be dropped first.

The following Java code snippet drops the table replica in region 2 (Phoenix region). Java code snippet is used for simplicity.

/* Drop table replica in us-phoenix-1 */
DropReplicaRequest dropRepReq = new DropReplicaRequest()
                                 .setTableName(tableName)
                                 .setReplicaName(region);
 
res = handle.dropReplica(dropRepReq);
res.waitForCompletion(handle, 60000, 500);

Change the Capacity Mode

Oracle NoSQL Database Cloud Service offers two capacity modes: provisioned capacity and on-demand capacity modes. For details on the capacity mode, refer to this page.  Organizations may want to start small with the provisioned capacity mode when new business opportunities emerge. As activities pick up, workloads may be hard to predict, and the on-demand capacity mode is ideal for initially monitoring and learning the workloads. 

The following Java code snippet configures a regional table replica’s capacity mode, changing from the provisioned capacity mode to the on-demand capacity mode.

/* Use the constructor to set storage capacity limit only for on-demand */
TableLimits limits = new TableLimits(1);
TableRequest treq = new TableRequest().setTableName(“<table_name>”).setTableLimits(limits);
TableResult tres = serviceHandle.tableRequest(treq);
tres.waitForCompletion(serviceHandle, 50000,3000);

Configure Time To Live (TTL)

Some business use cases may require table records to expire after a specific time. Global Active Table offers setting an expiry time on table rows, after which the rows expire automatically and are removed. The TTL settings in all regional table replicas are identical. When a row is replicated to other regions, its expiration time is replicated as an absolute timestamp. This specific row will expire simultaneously, irrespective of when it was replicated. For details, refer to this documentation.

The following Java code snippet creates Global Active Tables with TTL equals 10 days.

/* Step 1: Create a singleton table at the Ashburn region with TTL 10 days*/
String ddl = “CREATE TABLE IF NOT EXISTS ” + tableName +
                  “(id INTEGER, personInfo JSON, PRIMARY KEY(id)) ” +
                  “using TTL 10 days with schema frozen”;
 
TableRequest tableReq = new TableRequest()
            .setStatement(ddl)
            .setTableLimits(new TableLimits(50, 50, 1));
 
TableResult res = handle.tableRequest(tableReq);
        res.waitForCompletion(handle, 90000, 1000);
 
/* Step 2: Add replica at the Phoenix region */
AddReplicaRequest addRepReq = new AddReplicaRequest()
                .setTableName(tableName)
                .setReplicaName(region);
        res = handle.addReplica(addRepReq);
        res.waitForCompletion(handle, 90000, 1000);

 

Summary

B u s i n e s s   A g i l i t y   a t    t h e    S p e e d   o f    C h a n g e    a n d    O p p o r t u n i t y

When enterprises boldly take on new opportunities and changes, they must innovate and evolve their businesses fast to meet customers’ demands. They must be agile, empowering different product teams to make choices to achieve their goals. However, agility may result in complexity, which businesses can’t afford.

Global Active Tables unravel all the technical complexities, enabling different teams to dynamically configure data platforms for their business applications at the global scale. Programmatic interfaces glue all the pieces together with just a few lines of code and deploy different data platforms in minutes, hiding all underlying complexities. This companion blog covers the technical details on Global Active Tables’ underlying architecture, configuration, and operation.

Join me! Get on the ride! Grab your pass with this getting started guide.