2025年1月6日月曜日

RDF Graph Support for Apache Jenaを使ってみる

Oracle RDF Graph Adaptor for Eclipse RDF4Jでは、スキーマプライベート・ネットワークのRDFグラフを扱えませんでした(こちらの記事)。RDF Graph Support for Apache Jenaはスキーマプライベート・ネットワークを扱うことができるため、Oracle Database 23aiやAutonomous DatabaseをRDFグラフの保存先にできます。

今回の記事ではRDF Graph Support for Apache Jenaのセットアップ方法を確認します。参照するドキュメントは以下です。

RDFグラフのグラフ開発者ガイド Release 23
7 RDF Graph Support for Apache Jena
https://docs.oracle.com/cd/G11854_01/rdfrm/rdf-graph-support-apache-jena.html

Oracle Graph Server and Clientのダウンロード・ページにあるOracle Graph - Support Adaptors and Pluginsは正しいアーカイブにリンクされていません。そのため、Oracle Software Delivery Cloud(Oracle E-Delivery)にサインインして、Oracle Graph - Support Adaptors and Pluginsをダウンロードします。

Oracle Graph - Support Adaptors and Plugins 21.1がRDF Graph Support for Apache Jenaが含まれるアーカイブです。21.2の方はバージョンの高いプラグインが含まれているわけではなく、違うプラグイン(具体的にはCytoscapeへのプラグイン)が含まれています。

このアーカイブはV1042773-01.zipとしてダウンロードされます。


作業はmacOS上で実施します。あまりホストの環境に変更を加えないように、Eclipse RDF4Jと同様にJDK11をインストールしたコンテナを作成します。

Oracle Graph - Support Adaptors and Plugin 21.1には、3種類のプラグインが含まれます。
  1. Apache Jena 3.12.0のプラグイン
  2. Apache Jena Fuseki 3.12.0のプラグイン(Jettyを含みます)
  3. Protege Desktop 5.5のプラグイン
これらのプラグインを使っている以下の2種類の機能について、動作を確認します。Protege Desktopのプラグインについては(macOSのProtege DesktopにProtege Pluginの組み込みが困難だったため)、今回の作業からは除外します。
  1. Apache Jena Fuseki(バンドルされたJettyをWebサーバーとして使用)
  2. バルクローダーのorardfldr
最初に適当なフォルダを作成し、作業に使用するファイルを配置します。Apache JenaはV1042773-01.zipに含まれているため、Apache Jenaのサイトからダウンロードする必要はありません。

ベースの環境としてOracle Linux 8およびJava11を使います。GitHubで公開されているOracleのDockerfileより、OracleJavaの11のOL8向けDockerfile.ol8をダウンロードします。
https://github.com/oracle/docker-images/tree/main/OracleJava/11


ファイル名をDockerfileとして、最後のjshellの起動をshに変更します。

CMD ["sh"]

JDK11をダウンロードします。


アーキテクチャに合わせて、ARM64かx64のどちらかのCompressed Archiveをダウンロードします。


ちなみに、JDK21とJDK23ではOracle No-Fee Terms and Conditions(NFTC)が適用されるため、コンテナ・イメージのビルド中にJDKのアーカイブをダウンロードします。そのため、あらかじめJDKをダウンロードする必要はありません(JDK 21や23ではApache Jena Fusekiが動作しなかったので、JDK11を使用するのが安全です)。

今回はオラクル・データベースにRDFのスキーマプライベート・ネットワークを作成した上で、RDFグラフを作成します。スキーマプライベート・ネットワークはローカルのコンテナ環境で動作しているOracle Database 23ai Freeに作成します。この環境はOracle APEXをローカルのコンテナ環境に作成した際に同時に作成したデータベースで、RDFのデータはAPEXのワークスペース・スキーマに保存します。

Oracle Database 23ai Freeでデフォルトで作成されるPDB、FREEPDB1ユーザーsystemで接続し、APEXのワークスペース・スキーマWKSP_APEXDEVにスキーマプライベート・ネットワークとしてLOCALNETを作成します。Oracle Database 23ai Freeなので、表領域はデフォルトで作成されるUSERSを指定します。
begin
    sem_apis.create_rdf_network(
        tablespace_name => 'USERS'
        ,network_owner  => 'WKSP_APEXDEV'
        ,network_name   => 'LOCALNET'
    );
end;
/

SQL> begin

  2      sem_apis.create_rdf_network(

  3          tablespace_name => 'USERS'

  4          ,network_owner  => 'WKSP_APEXDEV'

  5          ,network_name   => 'LOCALNET'

  6      );

  7  end;

  8* /


PL/SQLプロシージャが正常に完了しました。


SQL> 


ワークスペース・スキーマWKSP_APEXDEVで接続し、RDFグラフとしてMYTHを作成します。
begin
    sem_apis.create_rdf_graph(
        rdf_graph_name => 'MYTH'
        ,table_name    => null
        ,column_name   => null
        ,network_owner => 'WKSP_APEXDEV'
        ,network_name  => 'LOCALNET'
    );
end;
/

SQL> begin

  2      sem_apis.create_rdf_graph(

  3          rdf_graph_name => 'MYTH'

  4          ,table_name    => null

  5          ,column_name   => null

  6          ,network_owner => 'WKSP_APEXDEV'

  7          ,network_name  => 'LOCALNET'

  8      );

  9  end;

 10* /


PL/SQLプロシージャが正常に完了しました。


SQL> 


このRDFグラフに保存するデータとして、以下を使用します。ChatGPTにプロンプトとして「ギリシャ神話の神々の関係をRDFのRDF/XML形式で表現してください。」を与えて生成しました。最初はTurtle形式を指定したのですが、それは上手く生成してくれませんでした。XMLやJSONの方が書式を間違えにくいのではと思います。


このデータをApache Jena Fusekiおよびorardfldrを使って、オラクル・データベースのRDFグラフに保存します。

RDF Graph Support for Apache Jenaを実装するコンテナ・イメージを作成します。podman buildを実行するディレクトリには、以下のファイルが配置されている状態です。

% ls

Dockerfile greek.xml

V1042773-01.zip jdk-11.0.25_linux-aarch64_bin.tar.gz

% 


以下のコマンドを実行します。

podman build --file Dockerfile --tag oracle-jena:3.12.0

% podman build --file Dockerfile --tag oracle-jena:3.12.0

[1/2] STEP 1/8: FROM oraclelinux:8 AS builder

[1/2] STEP 2/8: LABEL maintainer="Aurelio Garcia-Ribeyro <aurelio.garciaribeyro@oracle.com>"

--> 4181204e70d1

[1/2] STEP 3/8: RUN dnf install -y tar

Oracle Linux 8 BaseOS Latest (aarch64)           44 MB/s | 123 MB     00:02    

Oracle Linux 8 Application Stream (aarch64)      39 MB/s |  58 MB     00:01    

Last metadata expiration check: 0:00:07 ago on Mon Jan  6 08:09:18 2025.

Package tar-2:1.30-9.el8.aarch64 is already installed.

Dependencies resolved.

Nothing to do.

Complete!

--> b14e96fb42ce

[1/2] STEP 4/8: ENV LANG en_US.UTF-8

--> dd8246a0212f

[1/2] STEP 5/8: ENV JAVA_HOME=/usr/java/jdk-11

--> 38f27ce23e52

[1/2] STEP 6/8: COPY *.tar.gz /tmp/

--> 6671e7397a2c

[1/2] STEP 7/8: SHELL ["/bin/bash", "-o", "pipefail", "-c"]

time="2025-01-06T17:09:28+09:00" level=warning msg="SHELL is not supported for OCI image format, [/bin/bash -o pipefail -c] will be ignored. Must use `docker` format"

--> 6e9a8f099284

[1/2] STEP 8/8: RUN set -eux;     ARCH="$(uname -m)" &&     if [ "$ARCH" = "x86_64" ];     then     mv "$(ls /tmp/jdk-11*_linux-x64_bin.tar.gz)" /tmp/jdk.tar.gz ;         JAVA_SHA256=d22d0fcca761861a1eb2f5f6eb116c933354e8b1f76b3cda189c722cc0177c98 ;     else     mv "$(ls /tmp/jdk-11*_linux-aarch64_bin.tar.gz)" /tmp/jdk.tar.gz ;         JAVA_SHA256=3fc0d93f6363d32723c293ba5a9016e8ab27410351ed804020cfe71e87d3bc0a ;     fi &&     echo "$JAVA_SHA256 */tmp/jdk.tar.gz" | sha256sum -c -;     mkdir -p "$JAVA_HOME";     tar --extract --file /tmp/jdk.tar.gz --directory "$JAVA_HOME" --strip-components 1

++ uname -m

+ ARCH=aarch64

+ '[' aarch64 = x86_64 ']'

++ ls /tmp/jdk-11.0.25_linux-aarch64_bin.tar.gz

+ mv /tmp/jdk-11.0.25_linux-aarch64_bin.tar.gz /tmp/jdk.tar.gz

+ JAVA_SHA256=3fc0d93f6363d32723c293ba5a9016e8ab27410351ed804020cfe71e87d3bc0a

+ echo '3fc0d93f6363d32723c293ba5a9016e8ab27410351ed804020cfe71e87d3bc0a */tmp/jdk.tar.gz'

+ sha256sum -c -

/tmp/jdk.tar.gz: OK

+ mkdir -p /usr/java/jdk-11

+ tar --extract --file /tmp/jdk.tar.gz --directory /usr/java/jdk-11 --strip-components 1

time="2025-01-06T17:09:30+09:00" level=warning msg="SHELL is not supported for OCI image format, [/bin/bash -o pipefail -c] will be ignored. Must use `docker` format"

--> 97b5278123a8

[2/2] STEP 1/7: FROM oraclelinux:8

[2/2] STEP 2/7: ENV LANG en_US.UTF-8

--> Using cache 8964bc11495eb33b855f9d79cee5244aadc444312f6eefa71dd19a2b6d5f4fbc

--> 8964bc11495e

[2/2] STEP 3/7: ENV JAVA_HOME=/usr/java/jdk-11

--> Using cache af690fa3099471930289d030dd9e65fd489cadb9d1efc991aceda9fdd8287bd6

--> af690fa30994

[2/2] STEP 4/7: ENV PATH $JAVA_HOME/bin:$PATH

--> Using cache 9673faba6264bf0613a2771c3d5da856952cf3fd4caa1bdfd444fb9d4f944225

--> 9673faba6264

[2/2] STEP 5/7: COPY --from=builder $JAVA_HOME $JAVA_HOME

--> Using cache d7b0bf61180264d094df0d235035f07d1b1ed1a20cc62f6cb965b6387765be8f

--> d7b0bf611802

[2/2] STEP 6/7: RUN set -eux;     dnf -y update;     dnf install -y         freetype fontconfig     ;     rm -rf /var/cache/dnf;     ln -sfT "$JAVA_HOME" /usr/java/default;     ln -sfT "$JAVA_HOME" /usr/java/latest;     for bin in "$JAVA_HOME/bin/"*; do         base="$(basename "$bin")";         [ ! -e "/usr/bin/$base" ];         alternatives --install "/usr/bin/$base" "$base" "$bin" 20000;     done;     java -Xshare:dump;

--> Using cache 9ae7f7c9cd08af81d0902995d979be82dade222b9e67cceaf425d78e019b873e

--> 9ae7f7c9cd08

[2/2] STEP 7/7: CMD ["sh"]

--> Using cache 88f354a5474f88715d804bb75a6c8e8feb232d2f61c639b0989463604b57400b

[2/2] COMMIT oracle-jena:3.12.0

--> 88f354a5474f

Successfully tagged localhost/oracle-jena:3.12.0

Successfully tagged localhost/eclipse-rdf4j:4.2.4

Successfully tagged localhost/rdf4j-workbench:5.0.3

88f354a5474f88715d804bb75a6c8e8feb232d2f61c639b0989463604b57400b

% 


作成したコンテナ・イメージより、RDF Graph Support for Apache Jenaを実行するコンテナを作成します。Apache Jena Fusekiはデフォルトで3030番ポートでHTTPの接続を待ち受けするため、ホスト・ポートの3030にマップします。podman buildを実行したカレント・ディレクトリを/opt/oracleから参照できるようにマップしています。

echo "exit" | podman run --name oracle-jena -i -p 3030:3030 -v `pwd`:/opt/oracle localhost/oracle-jena:3.12.0

% echo "exit" | podman run --name oracle-jena -i -p 3030:3030 -v `pwd`:/opt/oracle localhost/oracle-jena:3.12.0

%


作成したコンテナoracle-jenaを起動し、bashで接続します。

podman start oracle-jena
podman exec -it oracle-jena bash

% podman start oracle-jena

oracle-jena

% podman exec -it oracle-jena bash

[root@9b5d51aee412 /]# 


V1042773-01.zipを解凍するためにunzipをインストールします。

dnf -y install unzip

[root@9b5d51aee412 oracle]# dnf -y install unzip

Oracle Linux 8 BaseOS Latest (aarch64)                                                    44 MB/s | 123 MB     00:02    

Oracle Linux 8 Application Stream (aarch64)                                               36 MB/s |  58 MB     00:01    

Last metadata expiration check: 0:00:07 ago on Mon 06 Jan 2025 08:16:33 AM UTC.

Dependencies resolved.

=========================================================================================================================

 Package               Architecture            Version                           Repository                         Size

=========================================================================================================================

Installing:

 unzip                 aarch64                 6.0-47.0.1.el8_10                 ol8_baseos_latest                 189 k


Transaction Summary

=========================================================================================================================

Install  1 Package


Total download size: 189 k

Installed size: 474 k

Downloading Packages:

unzip-6.0-47.0.1.el8_10.aarch64.rpm                                                      470 kB/s | 189 kB     00:00    

-------------------------------------------------------------------------------------------------------------------------

Total                                                                                    464 kB/s | 189 kB     00:00     

Running transaction check

Transaction check succeeded.

Running transaction test

Transaction test succeeded.

Running transaction

  Preparing        :                                                                                                 1/1 

  Installing       : unzip-6.0-47.0.1.el8_10.aarch64                                                                 1/1 

  Running scriptlet: unzip-6.0-47.0.1.el8_10.aarch64                                                                 1/1 

  Verifying        : unzip-6.0-47.0.1.el8_10.aarch64                                                                 1/1 


Installed:

  unzip-6.0-47.0.1.el8_10.aarch64                                                                                        


Complete!

[root@9b5d51aee412 oracle]# 


/opt/oracleに移動し、V1042773-01.zip/opt以下に解凍します。

cd /opt/oracle
unzip -d /opt V1042773-01.zip

/opt以下にディレクトリとして21.1.5_Oracle19c_Jena-3.12.0__MACOSXが作成されます。

[root@9b5d51aee412 oracle]# cd /opt/oracle

[root@9b5d51aee412 oracle]# pwd

/opt/oracle

[root@9b5d51aee412 oracle]# unzip -d /opt V1042773-01.zip 

Archive:  V1042773-01.zip

   creating: /opt/21.1.5_Oracle19c_Jena-3.12.0/

  inflating: /opt/__MACOSX/._21.1.5_Oracle19c_Jena-3.12.0  

  inflating: /opt/21.1.5_Oracle19c_Jena-3.12.0/bug_notes.txt  

  inflating: /opt/__MACOSX/21.1.5_Oracle19c_Jena-3.12.0/._bug_notes.txt  

   creating: /opt/21.1.5_Oracle19c_Jena-3.12.0/fuseki-web-app/

  inflating: /opt/__MACOSX/21.1.5_Oracle19c_Jena-3.12.0/._fuseki-web-app  

   creating: /opt/21.1.5_Oracle19c_Jena-3.12.0/sparqlgateway-web-app/

  inflating: /opt/__MACOSX/21.1.5_Oracle19c_Jena-3.12.0/._sparqlgateway-web-app  

   creating: /opt/21.1.5_Oracle19c_Jena-3.12.0/bin/

  inflating: /opt/__MACOSX/21.1.5_Oracle19c_Jena-3.12.0/._bin  

   creating: /opt/21.1.5_Oracle19c_Jena-3.12.0/jar/

  inflating: /opt/__MACOSX/21.1.5_Oracle19c_Jena-3.12.0/._jar  

   creating: /opt/21.1.5_Oracle19c_Jena-3.12.0/protege_plugin/

  inflating: /opt/__MACOSX/21.1.5_Oracle19c_Jena-3.12.0/._protege_plugin  

  inflating: /opt/21.1.5_Oracle19c_Jena-3.12.0/release_notes.txt  

  inflating: /opt/__MACOSX/21.1.5_Oracle19c_Jena-3.12.0/._release_notes.txt  

  inflating: /opt/21.1.5_Oracle19c_Jena-3.12.0/README  

  inflating: /opt/__MACOSX/21.1.5_Oracle19c_Jena-3.12.0/._README  

   creating: /opt/21.1.5_Oracle19c_Jena-3.12.0/examples/

  inflating: /opt/__MACOSX/21.1.5_Oracle19c_Jena-3.12.0/._examples  

  inflating: /opt/21.1.5_Oracle19c_Jena-3.12.0/version.txt  

  inflating: /opt/__MACOSX/21.1.5_Oracle19c_Jena-3.12.0/._version.txt  

   creating: /opt/21.1.5_Oracle19c_Jena-3.12.0/javadoc/


[中略]


  inflating: /opt/21.1.5_Oracle19c_Jena-3.12.0/javadoc/oracle/spatial/rdf/client/jena/assembler/package-tree.html  

  inflating: /opt/__MACOSX/21.1.5_Oracle19c_Jena-3.12.0/javadoc/oracle/spatial/rdf/client/jena/assembler/._package-tree.html  

  inflating: /opt/21.1.5_Oracle19c_Jena-3.12.0/javadoc/oracle/spatial/rdf/client/jena/assembler/OracleDatasetAssembler.html  

  inflating: /opt/__MACOSX/21.1.5_Oracle19c_Jena-3.12.0/javadoc/oracle/spatial/rdf/client/jena/assembler/._OracleDatasetAssembler.html  

[root@9b5d51aee412 oracle]# ls /opt

21.1.5_Oracle19c_Jena-3.12.0  __MACOSX  oracle

[root@9b5d51aee412 oracle]# 


ディレクトリ__MACOSXは不要なので削除します。

rm -rf /opt/__MACOSX

[root@9b5d51aee412 oracle]# rm -rf /opt/__MACOSX

[root@9b5d51aee412 oracle]# ls /opt

21.1.5_Oracle19c_Jena-3.12.0  oracle

[root@9b5d51aee412 oracle]# 


RDF Graph Support for Apache Jenaへのアクセスが容易になるように、/opt/oracle-jenaとしてシンボリック・リンクを作成します。

ln -s /opt/21.1.5_Oracle19c_Jena-3.12.0 /opt/oracle-jena

[root@9b5d51aee412 oracle]# ln -s /opt/21.1.5_Oracle19c_Jena-3.12.0 /opt/oracle-jena

[root@9b5d51aee412 oracle]# 


最初にApache Jena Fusekiを構成します。Apache Jena Fusekiが含まれているディレクトリへ移動します。

cd /opt/oracle-jena/fuseki

[root@9b5d51aee412 oracle]# cd /opt/oracle-jena/fuseki

[root@9b5d51aee412 fuseki]# ls

bin                fuseki         fuseki-server      fuseki-server.jar  NOTICE  run  webapp

config-oracle.ttl  fuseki-backup  fuseki-server.bat  LICENSE            README  tmp

[root@9b5d51aee412 fuseki]# 


移動したディレクトリ/opt/oracle-jena/fuseki以下にconfig-oracle.ttlがあります。Apache Jena Fusekiのデータセットの保存先としてオラクル・データベースを使用するための設定ファイルの雛形です。

この中のoracle:Datasetの設定のoracle:jdbcURLoracle:allGraphsを変更します。

今回はローカル環境のコンテナで実行されているOracle Database 23ai Freeに接続するため、oracle:jdbcURLHOSTとしてhost.containers.internalPORTとして1521SERVICE_NAMEとしてfreepdb1を指定します。oracle:UserはRDFグラフを作成したユーザーWKSP_APEXDEVoracle:PasswordはユーザーWKSP_APEXDEVのパスワードを指定します。oracle:Userの指定に限りませんが、オラクル・データベースに大文字として保存されている識別子については、大文字で指定します。

oracle:allGraphsoracle:firstModelMITHoracle:networkOwnerWKSP_APEXDEVoracle:networkNameLOCALNETを指定します。

oracle:allGraphsの末尾に // で始まるコメントがあります。コメントとして認識されずエラーになるので削除します。

# Custom code.

[] ja:loadClass "oracle.spatial.rdf.client.jena.assembler.OracleAssemblerVocab" .

oracle:Dataset  rdfs:subClassOf  ja:RDFDataset .


<#oracle> rdf:type oracle:Dataset;

    oracle:connection

    [ a oracle:OracleConnection ;

      oracle:jdbcURL "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=host.containers.internal)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=freepdb1)))";

      oracle:User "WKSP_APEXDEV" ;

      oracle:Password "******"

    ];

#    oracle:allGraphs [ oracle:firstModel "MODEL_NAME" ] .

    oracle:allGraphs [ oracle:firstModel "MYTH"; oracle:networkOwner "WKSP_APEXDEV"; oracle:networkName "LOCALNET" ] .


#


以上の変更を行ったconfig-oracle.ttlで、run/config.ttlを置き換えます。

cp config-oracle.ttl run/config.ttl

[root@9b5d51aee412 fuseki]# cp config-oracle.ttl run/config.ttl 

cp: overwrite 'run/config.ttl'? yes

[root@9b5d51aee412 fuseki]# 


デフォルトではlocalhostからのアクセスに限定されています。run/shiro.iniを開き、localhost以外からのアクセスを許可します。

/$/** = localhostFilterの行をコメントアウトします。
続いて、/$/** = anonの行からコメントを除き、有効にします。

[urls]

## Control functions open to anyone

/$/status = anon

/$/ping   = anon


## and the rest are restricted to localhost.

##/$/** = localhostFilter


## If you want simple, basic authentication user/password

## on the operations,

##    1 - set a better password in [users] above.

##    2 - comment out the "/$/** = localhost" line and use:

## "/$/** = authcBasic,user[admin]"


## or to allow any access.

/$/** = anon


# Everything else

/**=anon


以上でApache Jena Fusekiのサーバーを実行します。環境変数FUSEKI_HOMEが指定されていない場合は、実行時のカレント・ディレクトリがFUSEKI_HOMEとして認識されます。今回は/opt/oracle-jena/fusekiからfuseki-serverを実行しているため、環境変数FUSEKI_HOMEは指定してません。

sh fuseki-server

Apache Jena Fusekiのサーバーが起動します。

[root@9b5d51aee412 fuseki]# sh fuseki-server

SLF4J: Class path contains multiple SLF4J bindings.

SLF4J: Found binding in [jar:file:/opt/21.1.5_Oracle19c_Jena-3.12.0/fuseki/fuseki-server.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: Found binding in [jar:file:/opt/21.1.5_Oracle19c_Jena-3.12.0/jar/slf4j-log4j12-1.7.20.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.

SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

[2025-01-06 08:44:09] Server     INFO  Apache Jena Fuseki 3.12.0

[2025-01-06 08:44:09] Config     INFO  FUSEKI_HOME=/opt/oracle-jena/fuseki

[2025-01-06 08:44:09] Config     INFO  FUSEKI_BASE=/opt/oracle-jena/fuseki/run

[2025-01-06 08:44:09] Config     INFO  Shiro file: file:///opt/oracle-jena/fuseki/run/shiro.ini

[2025-01-06 08:44:09] IniRealm   WARN  Users or Roles are already populated.  Configured Ini instance will be ignored.

[2025-01-06 08:44:09] Config     INFO  Configuration file: /opt/oracle-jena/fuseki/run/config.ttl

[2025-01-06 08:44:09] OracleQueryProgressMonitor INFO  startMonitor: starts

[2025-01-06 08:44:10] Config     INFO  Register: /oracle

[2025-01-06 08:44:10] Server     INFO  Started 2025/01/06 08:44:10 UTC on port 3030



ブラウザよりApache Jena Fusekiのアクセスします。


dataset nameとして/oracleが含まれていることを確認します。


RDFデータをロードします。add dataをクリックします。


デフォルトのグラフにデータをロードするため、Destination graph name空白のままとします。Files to uploadをクリックし、greek.xmlを選択します。

ファイルを選択後、upload nowをクリックします


48 triplesのロードに成功したことを確認します。

queryをクリックし、ロードした内容をApache Jena Fusekiから確認します。


EXAMPLE QUERYSelection of triplesをクリックし、保存されているトリプルのうち25件を検索するSPARQLの問い合わせを実行します。

subject、predicate、objectの組みが25行検索されることが確認できれば、Apache Jena Fusekiの実装は完了です。


APEXのワークスペースにサインインし、SQLコマンドよりSEM_MATCHファンクションを使ってRDFグラフMYTHにロードされたトリプルを検索します。

以下のSQLを実行します。
select s$rdfterm, p$rdfterm, o$rdfterm
from table(sem_match(
    query => 'SELECT ?s ?p ?o WHERE { ?s ?p ?o }'
    , models => SEM_MODELS('MYTH')
    , rulebases => null
    , aliases => null
    , filter => null
    , index_status => null 
    , options =>' PLUS_RDFT=VC '
    , graphs => null
    , named_graphs => null
    , network_owner => 'WKSP_APEXDEV'
    , network_name => 'LOCALNET'
));
APEX側からもデータベースのロードされたRDFデータが確認できました。


orardfldrの動作を確認するため、RDFグラフMYTHを空にします。SEM_APIS.TRUNCATE_RDF_GRAPHを実行します。
begin
    sem_apis.truncate_rdf_graph(
        rdf_graph_name => 'MYTH'
        ,network_owner => 'WKSP_APEXDEV'
        ,network_name => 'LOCALNET'
    );
end;

先ほどと同じ問い合わせを実行し、RDFグラフMYTHの内容が空であることを確認します。


Apache Jena Fusekiから見ても、デフォルトのグラフの内容が空になっていることを確認します。


orardfldrを使ってgreek.xmlをデータベースにロードします。コンテナoracle-jenaに接続します。

podman exec -it oracle-jena bash

% podman exec -it oracle-jena bash

[root@9b5d51aee412 /]# 


環境変数ORACLE_JENA_HOME/opt/oracle-jenaを設定し、bin以下をPATHに含めます。

export ORACLE_JENA_HOME=/opt/oracle-jena
export PATH=$ORACLE_JENA_HOME/bin:$PATH

[root@9b5d51aee412 /]# export ORACLE_JENA_HOME=/opt/oracle-jena

[root@9b5d51aee412 /]# export PATH=$ORACLE_JENA_HOME/bin:$PATH

[root@9b5d51aee412 /]# 


ディレクトリ/opt/oracleに移動し、orardfldrのオンライン・ヘルプを表示します。

cd /opt/oracle
orardfldr --help

[root@9b5d51aee412 /]# cd /opt/oracle

[root@9b5d51aee412 oracle]# orardfldr --help

Usage: orardfldr --modelName=NAME --fileDir=DIR --lang=FMT --jdbcUrl=URL 

       --user="USER" --password=PASSWORD [--bulkLoadFlags="FLAGS"]

       [--networkName=NAME] [--networkOwner="OWNER"] [--numThreads=INT]

       [--proxyUser="USER"] [--rebuildAppTabIdx=BOOLEAN] [--truncateStgTab=BOOLEAN]

Performs an RDF bulk load of all files in a directory into Oracle Database.


  Mandatory Arguments:

    --modelName=NAME             Target semantic model for the load

    --fileDir=DIR                Data directory for the load

    --lang=FMT                   Data format (N-TRIPLE, RDF/XML, TURTLE,

                                 N-QUADS, TRIG)

    --jdbcUrl=URL                JDBC url for the target database

    --user="USER"                Database user name (case sensitive)

    --password=PASSWORD          Database user password


  Optional Arguments:

    --bulkLoadFlags="FLAGS"      Flags string to use with

                                 SEM_APIS.BULK_LOAD_FROM_STAGING_TABLE

    --networkName=NAME           Name of the semantic network to load into

                                 (Default MDSYS network if omitted)

    --networkOwner="OWNER"       Owner of the semantic network to load into

                                 (case sensitive, MDSYS is used if omitted)

    --numThreads=INT             Number of threads to use when populating

                                 the staging table (default 1)

    --proxyUser="USER"           Database proxy user name (case sensitive)

    --rebuildAppTabIdx=BOOLEAN   TRUE (default) to do bottom-up rebuilding

                                 of application table indexes

    --truncateStgTab=BOOLEAN     TRUE (default) to truncate pre-existing

                                 data in the staging table


[root@9b5d51aee412 oracle]# 


ロード対象のファイルは/opt/oracle/greek.xmlとして配置されていますが、ロード対象の指定はfileDir、つまりディレクトリである必要があります。そのためディレクトリdataを作成し、ロード対象のファイルgreek.xmlを作成したディレクトリdata以下に移動します。

mkdir data
mv greek.xml data

[root@9b5d51aee412 oracle]# mkdir data

[root@9b5d51aee412 oracle]# mv greek.xml data

[root@9b5d51aee412 oracle]#


orardfldrを呼び出します。

modelNameMYTHfileDirgreek.xmlを含む/opt/oracle/datalangはgreek.xmlのフォーマットであるRDF/XMLjdbcUrljdbc:oracle:thin:@host.containers.internal:1521/freepdb1userWKSP_APEXDEVpasswordにはユーザーWKSP_APEXDEVのパスワードを指定します。networkOwnerおよびnetworkNameは必須パラメータではありませんが、RDFグラフMYTHはスキーマプラベート・ネットワークに作成されているため、networkOwnerとしてWKSP_APEXDEVnetworkNameとしてLOCALNETを指定します。

orardfldr --modelName=MYTH --fileDir /opt/oracle/data --lang=RDF/XML --jdbcUrl="jdbc:oracle:thin:@host.containers.internal:1521/freepdb1" --user=WKSP_APEXDEV --password=<パスワード> --networkOwner=WKSP_APEXDEV --networkName=LOCALNET

[root@9b5d51aee412 oracle]# orardfldr --modelName=MYTH --fileDir=/opt/oracle/data --lang=RDF/XML --jdbcUrl="jdbc:oracle:thin:@host.containers.internal:1521/freepdb1" --user=WKSP_APEXDEV --password=********* --networkOwner=WKSP_APEXDEV --networkName=LOCALNET

log4j:WARN No appenders could be found for logger (oracle.spatial.rdf.client.jena.Parameters).

log4j:WARN Please initialize the log4j system properly.

log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

loadRDF: enabling parallel DDL/DML/query for session [0]

loadRDF: truncating staging tables

loadRDF in parallel: PrepareWorker [0] running

PrepareWorker: thread [0] done to 0, file = /opt/oracle/data/greek.xml in (ms) 211

loadRDF: preparing for bulk load

loadRDF: starting bulk load

loadRDF: bulk load flags="PARSE"

loadRDF: bulk load completed in (ms) 1313

[root@9b5d51aee412 oracle]# 


ロードが完了したら、先ほどと同じ手順でApache Jena Fusekiよりトリプルを検索します。


APEXのSQLコマンドからも、同様にSEM_MATCHを呼び出して検索します。


以上でRDF Graph Support for Apache Jenaに含まれるApache Jena Fusekiとorardfldrの基本的な動作確認ができました。

今回の記事は以上になります。