[Oracle Cloud] NoSQL Database Cloud Service を Java を使ってクイックスタートしてみた

# はじめに

Oracle Cloud Infrastructure(以下OCI)では、NoSQL Database Cloud Service が提供されています。フルマネージドな NoSQL サービスです。ユーザーはインスタンスを気にする必要なくデータストアを使うことが出来るのが特徴的です。

NoSQL Database Cloud Service へデータの書き込み・読み込みをするために、いくつか SDK が提供されています。今回の記事では、Java の SDK を使って、サンプルプログラムを動かす手順を確認していきます。



# 事前設定

CentOS7 上に、OpenJDK・Maven の環境を構築していること。環境が無い場合は、次のURLを参考に適当に構築します。
https://qiita.com/sugimount/items/a635473079d837b8944d



# SDK Download

SDK を手動でダウンロードして、Maven Project へ格納していきます。次のURLで公開されています。(Maven Repository として公開してほしい)

https://www.oracle.com/downloads/cloud/oracle-cloud-downloads.html#nosqlsdk

![1590917326814.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/5927e4ac-afc6-7923-db59-6a472a617bd2.png)



Download します

![1590917457862.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/5af256ee-dc7f-15c7-7f98-d55fea765dd2.png)



CentOS に持って行き、適当な場所で解凍します。

```
mkdir ~/work
mv oracle-nosql-java-sdk-5.2.11.tar.gz ~/work
cd ~/work
tar xfvz oracle-nosql-java-sdk-5.2.11.tar.gz
```



jar ファイルはこんな感じになっています。

```
[opc@maven lib]$ pwd
/home/opc/work/oracle-nosql-java-sdk-5.2.11/lib
[opc@maven lib]$ 
[opc@maven lib]$ ls -la
total 12220
drwxr-xr-x. 2 opc opc     143 May 31 07:14 .
drwxrwxr-x. 5 opc opc     132 May 31 07:14 ..
-rwxr-xr-x. 1 opc opc  796532 Feb 13 20:39 bcpkix-jdk15on.jar
-rwxr-xr-x. 1 opc opc 4189874 Feb 13 20:39 bcprov-jdk15on.jar
-rwxr-xr-x. 1 opc opc 2759505 Feb 13 20:39 guava.jar
-rwxr-xr-x. 1 opc opc  348136 Feb 13 20:39 jackson-core.jar
-rwxr-xr-x. 1 opc opc 4064246 Feb 13 20:39 netty-all.jar
-rwxr-xr-x. 1 opc opc  347011 Feb 13 20:39 nosqldriver.jar
```





# Maven Project に格納

まずは、Maven で Project を作ります。適当な名前で mkdir します。

```
mkdir -p ~/java
cd ~/java
```



Maven Project 作成 です。

```
mvn archetype:generate \
    -DarchetypeGroupId=org.apache.maven.archetypes \
    -DarchetypeArtifactId=maven-archetype-simple \
    -DarchetypeVersion=1.4 \
    -DgroupId=com.example \
    -DartifactId=nosql \
    -Dversion=1.0-SNAPSHOT \
    -Dpackage=com.example
```



作成した Project のなかで、NoSQL SDK を格納するためにディレクトリを作ります。 

```
cd ~/java/nosql
mkdir -p lib/repo/oraclenosqldriver/jars
```



pom.xml の依存関係の指定で、次の指定をします。version はよくわからないので、`none` としました。

```
  <dependencies>
    <dependency>
      <groupId>oracle.nosql.driver</groupId>
      <artifactId>nosqldriver</artifactId>
      <version>none</version>
      <scope>system</scope>
      <systemPath>${basedir}/lib/repo/oraclenosqldriver/jars/nosqldriver.jar</systemPath>
    </dependency>
  </dependencies>
```



手動で解凍した SDK の jar ファイル群を、作成したディレクトリにコピーします。

```
cp -p /home/opc/work/oracle-nosql-java-sdk-5.2.11/lib/* /home/opc/java/nosql/lib/repo/oraclenosqldriver/jars/
```



こんな感じになっています

```
[opc@maven nosql]$ ls -la /home/opc/java/nosql/lib/repo/oraclenosqldriver/jars/
total 12220
drwxrwxr-x. 2 opc opc     143 May 31 07:15 .
drwxrwxr-x. 3 opc opc      18 May 31 05:59 ..
-rwxr-xr-x. 1 opc opc  796532 Feb 13 20:39 bcpkix-jdk15on.jar
-rwxr-xr-x. 1 opc opc 4189874 Feb 13 20:39 bcprov-jdk15on.jar
-rwxr-xr-x. 1 opc opc 2759505 Feb 13 20:39 guava.jar
-rwxr-xr-x. 1 opc opc  348136 Feb 13 20:39 jackson-core.jar
-rwxr-xr-x. 1 opc opc 4064246 Feb 13 20:39 netty-all.jar
-rwxr-xr-x. 1 opc opc  347011 Feb 13 20:39 nosqldriver.jar
```



# Java Source Code

ここまでで SDK を使う準備が出来ました。[Get Started](https://docs.oracle.com/en/cloud/paas/nosql-cloud/ansct/index.html) で紹介されているサンプルプログラムを動かします。`SignatureProvider` の部分は、Get Started の Document を読んで事前設定が必要なので、ご注意ください。

ソースコードをぱっと見ればわかりますが、以下の操作をしています。

- Table の作成
- Table にデータ書き込み
- Table からデータ読み込み
- Table 削除

```java
package com.example;

import java.io.File;
import oracle.nosql.driver.NoSQLHandle;
import oracle.nosql.driver.NoSQLHandleConfig;
import oracle.nosql.driver.NoSQLHandleFactory;
import oracle.nosql.driver.Region;
import oracle.nosql.driver.iam.SignatureProvider;
import oracle.nosql.driver.ops.GetRequest;
import oracle.nosql.driver.ops.GetResult;
import oracle.nosql.driver.ops.PutRequest;
import oracle.nosql.driver.ops.PutResult;
import oracle.nosql.driver.ops.TableLimits;
import oracle.nosql.driver.ops.TableRequest;
import oracle.nosql.driver.ops.TableResult;
import oracle.nosql.driver.values.MapValue;

/**
 * Hello world!
 *
 */
public class App {
    /* Name of your table */
    final static String tableName = "HelloWorldTable";

    public static void main(String[] args) throws Exception {
        System.out.println("Start!");

        NoSQLHandle handle = generateNoSQLHandle();

        try {
            createTable(handle);
            writeRows(handle);
            readRows(handle);
            dropTable(handle);
        } catch (Exception e) {
            System.err.print(e);
        } finally {
            handle.close();
        }

        System.out.println("End!");
    }

    /* Create a NoSQL handle to access the cloud service */
    private static NoSQLHandle generateNoSQLHandle() throws Exception {

        SignatureProvider ap = new SignatureProvider(
                "ocid1.tenancy.oc1..secret",
                "ocid1.user.oc1..secret",
                "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00", new File("/home/opc/.oci/oci_api_key.pem"),
                "".toCharArray());

        /* Create a NoSQL handle to access the cloud service */
        NoSQLHandleConfig config = new NoSQLHandleConfig(Region.AP_TOKYO_1, ap);
        NoSQLHandle handle = NoSQLHandleFactory.createNoSQLHandle(config);
        return handle;
    }

    /**
     * Create a simple table with an integer key and a single string data field and
     * set your desired table capacity
     */
    private static void createTable(NoSQLHandle handle) throws Exception {
        String createTableDDL = "CREATE TABLE IF NOT EXISTS " + tableName + "(employeeid INTEGER, name STRING, "
                + "PRIMARY KEY(employeeid))";

        TableLimits limits = new TableLimits(1, 2, 1);
        TableRequest treq = new TableRequest().setStatement(createTableDDL).setTableLimits(limits);

        System.out.println("Creating table " + tableName);
        TableResult tres = handle.tableRequest(treq);

        /*
         * The request is async, so wait for the table to become active.
         */
        System.out.println("Waiting for " + tableName + " to become active");
        tres.waitForCompletion(handle, 60000, /* wait 60 sec */
                1000); /* delay ms for poll */
        System.out.println("Table " + tableName + " is active");
    }

    /**
     * Make a row in the table and write it
     */
    private static void writeRows(NoSQLHandle handle) throws Exception {
        MapValue value = new MapValue().put("employeeid", 1).put("name", "Tracy");
        PutRequest putRequest = new PutRequest().setValue(value).setTableName(tableName);
        PutResult putResult = handle.put(putRequest);
        if (putResult.getVersion() != null) {
            System.out.println("Wrote " + value);
        } else {
            System.out.println("Put failed");
        }
    }

    /**
     * Make a key and read the row from the table
     */
    private static void readRows(NoSQLHandle handle) throws Exception {
        MapValue key = new MapValue().put("employeeid", 1);
        GetRequest getRequest = new GetRequest().setKey(key).setTableName(tableName);
        GetResult getRes = handle.get(getRequest);
        System.out.println("Read " + getRes.getValue());
    }

    /**
     * Drop the table and wait for the table to move to dropped state
     */
    private static void dropTable(NoSQLHandle handle) throws Exception {
        System.out.println("Dropping table " + tableName);
        TableRequest treq = new TableRequest().setStatement("DROP TABLE IF EXISTS " + tableName);
        TableResult tres = handle.tableRequest(treq);
        System.out.println("Waiting for " + tableName + " to be dropped");
        tres.waitForCompletion(handle, 60000, /* wait 60 sec */
                1000); /* delay ms for poll */
        System.out.println("Table " + tableName + " has been dropped");
    }
}
```



実行例 in Visual Studio Code

```
[opc@maven nosql]$  cd /home/opc/java/nosql ; /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64/bin/java -Dfile.encoding=UTF-8 -cp /tmp/cp_2qd8pp7cihzbqrkegu8ef384z.jar com.example.App 
Start!
Creating table HelloWorldTable
Waiting for HelloWorldTable to become active
Table HelloWorldTable is active
Wrote {"name":"Tracy","employeeid":1}
Read {"employeeid":1,"name":"Tracy"}
Dropping table HelloWorldTable
Waiting for HelloWorldTable to be dropped
Table HelloWorldTable has been dropped
End!
```





# 参考URL

https://docs.oracle.com/en/cloud/paas/nosql-cloud/ansct/index.html