2025年8月1日金曜日

n8nのカスタム・ノードn8n-nodes-oracle-database-parameterizationを使ってOracle Databaseに接続する

Oracle Corporationで主にデータベースに接続するドライバのプロダクト・マネージメントを担当しているChristopher Jonesさんが、以下のブログ記事を公開しています。

How to create n8n workflows that connect to Oracle Database

jgriffin1さんがGitHubで公開しているn8n-nodes-oracle-database-parameterizationをインストールすると、カスタム・ノードとしてOracle Databaseに接続できるようです。

Christopher Jonesさんの元記事ではn8nがインストールされている環境があることを前提として、このカスタム・ノードをインストールしています。本記事ではn8nから提供されているコンテナ・イメージから作成したコンテナに対して、このカスタム・ノードをインストールしてみます。

以下のコマンドでn8nのコンテナを作成します。

podman run -it --rm --name n8n -e N8N_RUNNERS_ENABLED=true -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n

% podman run -it --rm --name n8n -e N8N_RUNNERS_ENABLED=true -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n

Initializing n8n process

n8n ready on ::, port 5678

n8n Task Broker ready on 127.0.0.1, port 5679

[license SDK] Skipping renewal on init because renewal is not due yet or cert is not initialized

Registered runner "JS Task Runner" (gXBJ9F_2r4CJr94jMWOP9) 

Version: 1.104.1


Editor is now accessible via:

http://localhost:5678


Press "o" to open in Browser.


別ターミナルからコンテナn8nに接続します。

podman exec -it n8n sh

 % podman exec -it n8n sh

~ $ 


カスタム・ノードをイントールするディレクトリとして、.n8n/custom/nodesを作成し、そのディレクトリ以下にn8n-nodes-oracle-database-parameterizationをインストールします。

mkdir -p ~/.n8n/custom/nodes
cd ~/.n8n/custom/nodes
npm install n8n-nodes-oracle-database-parameterization

~ $ mkdir -p ~/.n8n/custom/nodes

~ $ cd ~/.n8n/custom/nodes

~/.n8n/custom/nodes $ npm install n8n-nodes-oracle-database-parameterization


added 2 packages in 1s

npm notice

npm notice New minor version of npm available! 11.4.2 -> 11.5.2

npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.5.2

npm notice To update run: npm install -g npm@11.5.2

npm notice

~/.n8n/custom/nodes $ 


コンテナを再起動します。--rmオプションを付けてコンテナを開始しているため、正確にはコンテナの再作成が行われます。/home/node/.n8n以下はボリュームn8n_dataにマウントされているため、インストールしたカスタム・ノードも維持されます。

起動されているn8nを停止し、再度コンテナn8nの作成と起動を実施します。

podman run -it --rm --name n8n -e N8N_RUNNERS_ENABLED=true -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n

Press "o" to open in Browser.

Received SIGINT. Shutting down...

[Task Runner]: Received SIGTERM signal, shutting down...

[Task Runner]: Task runner stopped


Stopping n8n...

~ % podman run -it --rm --name n8n -e N8N_RUNNERS_ENABLED=true -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n

Initializing n8n process

n8n ready on ::, port 5678

n8n Task Broker ready on 127.0.0.1, port 5679

[license SDK] Skipping renewal on init because renewal is not due yet or cert is not initialized

Registered runner "JS Task Runner" (5KUqY3j-cv2g2z7wWTGLr) 

Version: 1.104.1


Editor is now accessible via:

http://localhost:5678


Press "o" to open in Browser.


n8nが起動したので、アクセスします。すでにn8nの画面を開いている場合は、ページを再ロードします。


Create Workflowをクリックし、新規にワークフローを作成します。

最初のノードとしてTrigger manuallyを作成します。


ノードを追加します。Oracleで検索するとOracle Database with Parameterizationが見つかります。これを追加します。


Oracle Databaseへの接続を確認するだけなので、SQL Statementselect * from dualを設定します。

Credential to connect withwksp_apexdev@local containerという名前で新規作成しました。


n8nのコンテナと同じく、コンテナで実行されているOracle Database 23ai Freeに接続するクリデンシャルを作成しています。

Connection Stringhost.containers.internal/freepdb1としています。


以上の設定を行いExecute stepをクリックすると、select * from dualが実行されます。


n8nのノードでOracle Databaseにアクセスできることが確認できました。

Christopher Jonesさんの記事では、もっと色々な操作を行なっています。n8nでオラクルを扱うにあたって、最初に参照されることをお勧めします。

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

2025年7月31日木曜日

APEXアプリケーションからn8nのワークフローを呼び出す

n8nで定義したワークフローをOracle APEXのアプリケーションから呼び出してみます。また、ワークフローの処理に時間がかかる場合を想定して、n8nのワークフローよりOracle REST Data ServicesのREST APIを呼び出す手順を確認します。

n8nには色々なアプリケーションと連携するアクションが標準で含まれていますが、Oracle APEXやOracle Databaseと連携するアクションは見つかりませんでした。そのため、APEXアプリケーションからの呼び出しをWebhookで受け付け、HTTP RequestでORDSのREST APIを呼び出します。

以下のワークフローをn8nで作成しています。中間のCodeでは以下のJavaScriptのコードを実行し、受信したデータをそのまま出力に渡しています。

return $input.all();


APEXアプリからのn8nのWebhookの呼び出し、および、n8nのHTTP RequestでのORDS REST APIの呼び出しは、基本的にREST APIの呼び出しなので難しいことはありませんが、認証については少し工夫が必要です。本記事は、主に認証での工夫について説明しています。

以下より、実施した検証作業を紹介します。作業はApple SiliconのMacbook Proで実施しています。

Oracle APEXについては、こちらの記事「podmanを使ってOracle Database FreeとOracle REST Data Servicesをコンテナとして実行する」で紹介している手順で作成した環境を使用します。

n8nを動かすサーバーを準備します。n8n Community Editionをコンテナとして実行します。公式ドキュメントのDocker Installationに記載されている手順に沿って、作業を実施します。

最初にボリュームを作成します。作成したボリュームにすべてのデータを保存するため、ボリュームが維持されていれば、コンテナを作り直してもそれまでの作業は維持されるようです。

podman volume create n8n_data

% podman volume create n8n_data

n8n_data

% 


n8nを実行するコンテナをn8nという名前で作成します。

-e N8N_RUNNERS_ENABLED=true および -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true のオプションについては、指定しないと警告が表示されたので追加しました。

podman run -it --rm --name n8n -e N8N_RUNNERS_ENABLED=true -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n

% podman run -it --rm --name n8n -e N8N_RUNNERS_ENABLED=true -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n

No encryption key found - Auto-generating and saving to: /home/node/.n8n/config

Initializing n8n process

n8n ready on ::, port 5678

Migrations in progress, please do NOT stop the process.

Starting migration InitialMigration1588102412422

Finished migration InitialMigration1588102412422


[中略]



n8n Task Broker ready on 127.0.0.1, port 5679

[license SDK] Skipping renewal on init because renewal is not due yet or cert is not initialized

Registered runner "JS Task Runner" (IFWQndGFfYn8ZyDN5Bma5) 

Version: 1.104.1


Editor is now accessible via:

http://localhost:5678


Press "o" to open in Browser.



オプション -p 5678:5678 を指定して、コンテナのポート5678をホストのポート5678にマップしています。ホストのブラウザからは、以下のURLでn8nにアクセスします。

http://localhost:5678/

最初にオーナー・アカウントの設定が求められます。以降は会社の規模や職種、利用者の役職や利用目的などの入力を求められます。


今回の作業はAPEXアプリケーションからの呼び出しができれば良かったので、Get paid features for free (forever)についてはskipしました。

アカウントの設定が完了すると、n8nのコンソールが開きます。

ワークフローの作成はスクラッチから始めます。


最初のノードとしてWebhookを追加します。


Webhookの基本的な設定を行います。

HTTP MethodPOSTRespondWhen Last Node FinishesResponse DataAll Entriesとします。


AuthenticationをクリックするとBasic AuthHeader AuthJWT AuthNoneの4つの選択肢が表示されます。認証が簡単なのはBasic Authですが、今回はJWT Authを選びます。

Credential for JWT Authをクリックして、+ Create new credentialを実行します。


JWTの署名の生成に関わる情報を設定します。今回は、APEX側ではAPEX_JWT.ENCODEを呼び出してJWTを生成する予定です。そのため、署名アルゴリズム(Algorithm)として選択できるのはHS256のみになります。HS256はハッシュ・アルゴリズムなのでKey TypePassphraseになります。Secretパスフレーズである文字列を入力します。この文字列を秘密キーとして、Oracle APEXのアプリケーションと共有します。

クリデンシャルの名前をAPEX Authに変更し、Saveします。


以上で、APEXアプリからの呼び出しを受け付けるWebhookが設定できました。

Webhook URLをコピーし、キャンバスに戻ります。


Webhookの後続のノードとしてCode(JavaScriptの実行)を追加します。


ModeRun Once for All itemsLanguageJavaScriptJavaScriptに以下を記述します。

return $input.all();

以上の設定を行い、キャンバスに戻ります。


この時点で一旦ワークフローをSaveします。


Execute Workflowをクリックします。WebhookにWaiting for you to call the Test URLと表示されているように、Webhookの呼び出し待ちになります。


APEXでの作業に移り、このn8nのワークフローを呼び出すAPEXアプリケーションを作成します。

空のAPEXアプリケーションを作成します。名前Call n8n Workflowとします。


アプリケーションが作成されます。機能はすべてホーム・ページに作成します。

ホーム・ページページ・デザイナで開きます。


最初にボタンSUBMITを作成します。n8nのWebhookを呼び出し、ワークフローを開始するボタンです。

外観ホットオンテンプレート・オプションWidthStretchにします。動作アクションはデフォルトのページの送信です。


送信するデータを入力するページ・アイテムP1_REQUESTを作成します。タイプテキスト領域です。外観高さ15に拡張しておきます。


同様にn8nのワークフローからのレスポンスを表示するページ・アイテムP1_RESPONSEを作成します。P1_REQUESTの右隣に配置するため、レイアウト新規行の開始オフにします。


ボタンSUBMITをクリックしたときに実行されるプロセスを作成します。

プロセスの名前Call n8n Workflowとします。タイプコードを実行ソースPL/SQLコードとして以下を記述します。


サーバー側の条件ボタン押下時SUBMITを指定します。


コード中でWebhook URLG_WEBHOOK_URLシークレットG_SECRETから参照しています。これらはアプリケーション定義置換文字列として設定します。

APEXをpodmanのコンテナとして実行している場合は、Webhook URLのlocalhostの部分は、host.containers.internalに置き換える必要があります。

置換文字列G_WEBHOOK_URLとしてWebhookのURLG_SECRETとしてAPEX Auth作成時に設定したSecretの文字列を設定します。


シークレットのような秘密の値を置換文字列として設定するのは、安全な方法ではありません。実際に運用する場合は、Oracle CloudであればVaultなどにシークレットとして保存するなど、安全を確保するためにもう一工夫が必要です。

以上で、APEXアプリケーションからn8nのワークフローを開始できるようになりました。

n8nのワークフローがWaiting for triggering eventの状態であることを確認します。


RequestにJSONを入力し、ボタンSubmitをクリックします。ワークフローは入力をエコーバックするだけなので、正しいJSONであれば内容はなんでも構いません。

ワークフローが返すレスポンスが表示されます。内容を見ると、送信したリクエストの他にHTTPヘッダーやJWTに含まれるiss、sub、audoの値なども参照できることが確認できます。


n8nのコンソールではWorkflow executed successfullyと表示され、ワークフローが終了します。


以上で、APEXアプリからn8nのワークフローを開始できるようになりました。

次にn8nのワークフローからのコールバックを実装します。

最初にn8nからコールバックされた内容を保持する表N8N_CALLBACKを作成します。



n8nから呼び出すOracle REST Data ServicesのREST APIを作成します。

モジュールとしてn8n、テンプレートとしてcallback、POSTハンドラとして以下のコードを記述しています。
begin
    insert into n8n_callback(response) values(:body_text);
    commit;
end;


作成したREST APIをOAuth2で保護します。

コードを実行するとclient_idclient_secretが印刷されます。一度しか印刷されないので、コピーして保存します。この値をn8n側に設定します。


コピーを忘れてしまった場合は、スクリプトを再実行します。

APEXアプリケーションのホーム・ページに、表N8N_CALLBACKの内容を表示する対話モード・レポートを追加します。

識別名前n8n Callbackソース表名N8N_CALLBACKを設定します。


以上でAPEXアプリケーションの準備は完了です。

n8nのワークフローにHTTP Requestのノードを追加します。


HTTP Requestに、以下の設定を行います。

MethodPOSTURLはORDSのREST APIのURLを指定します。モジュール・パスが/n8n/、テンプレート名がcallbackとして作成しているため、以下の形式になります。

http://ホスト:ポート/ords/ワークスペース名/n8n/callback

今回の作業ではワークスペース名apexdev、n8nはコンテナで動作しているため、以下を設定しています。

http://host.containers.internal:8181/ords/apexdev/n8n/callback

AuthenticationGeneric Credential TypeGeneric Auth TypeOAuth2 APIを選択します。OAuth2 APIAPEX OAuth2 Credを設定していますが、この設定については、この後に紹介します。

Send Bodyオンにし、Body Content TypeJSONSpecify BodyUsing JSONJSON{{ $json.body }}を設定します。入力されたJSONドキュメントを、ORDS REST APIの呼び出しの本体としてそのまま返しています。


APEX OAuth2 Credとして、以下を設定しています。

Grant TypeClient Credentialsです。Access Token URLはORDSが標準で提供しているトークンURLで、以下の形式になります。

http://ホスト:ポート/ords/ワークスペース名/oauth/token

今回の作業ではワークスペース名apexdev、n8nはコンテナで動作しているため、以下を設定しています。

http://host.containers.internal:8181/ords/apexdev/oauth/token

Client IDおよびClient Secretは、APEX側でOAuth2による保護を行なうスクリプトを実行した時にclient_idおよびclient_secretとして印刷された値を設定します。

ScopeにはORDSのモジュールの保護に使用した権限名を設定します。今回はn8n.privを設定します。

ORDSのトークンURLは、client_idおよびclient_secretはAuthorizationヘッダーとして送信されることを期待しているため、AuthenticationにはHeaderを設定します。


以上で、n8nのワークフローの更新は完了です。

ワークフローを実行します。


改変したAPEXアプリケーションからワークフローを開始します。

Requestに以下を入力し、ボタンSubmitをクリックします。

{
    "name": "my first request"
}

ワークフローがすぐに終了するため、ページの再描画前にn8nのワークフローからのコールバックが完了するようです。

そのため、対話モード・レポートにRequestとして与えた文字列がすぐに表示されます。


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

簡単なアプリケーションですが、作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/call-n8n-workflow.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。

2025年7月30日水曜日

Oracle Graph Quickstart Container ImageからOracle Graphの環境を作成する

Oracle CorporationのGraph機能を開発しているチームから、Oracle Graph Quickstart Container Imageが提供されています。container-registry.oracle.comからダウンロードできます。

Graph Developer's Guide for Property Graph, Release 25.2

コンテナ・イメージにはOracle Database 23ai FreeのLiteバージョンとOracle Graph Serverが含まれています。また、データベースにはあらかじめユーザーGRAPHUSERが作成され、そのスキーマに表BANK_ACCOUNTSとBANK_TRANSFERSがサンプル・データ込みで作成されています。そのため、このコンテナ・イメージをもとにOracle Graphのコンテナを作成して実行すると、すぐにOracle Graphの例題に取り掛かることができます。

残念なことに、x86_64限定でARM64版がありません。Apple SiliconのApple Macを使っている方(ほとんどの方はそうなはず)は、このコンテナ・イメージを使うことができません

x86_64の環境を持っている方向けに、このコンテナ・イメージを使う手順をまとめてみます。Oracle Graph Quickstart Container Imageをダウンロードするには、Oracle Accountによる認証が必要です。

以下よりコンテナを作成するまでの手順を紹介します。

Oracle Container RegistryのGraph Quickstartのページを開きます。

https://container-registry.oracle.com/ords/ocr/ba/database/graph-quickstart

「Please sign in using your Oracle Account to accept the license agreement for the Oracle container you have selected.」と記載されている下にあるボタンSign Inをクリックし、Oracle Accountにてサインインします。


以下のスクリーンショットは使用条件に同意した後の表示ですが、赤い四角で囲った領域で使用条件への同意を求められます。案内に従って、使用条件を確認した上で同意します。


画面右上のアカウントのメニューより、Auth Tokenを呼び出します。


Generate Secret Keyをクリックします。


Copy Secret Keyをクリックし、コンテナ・イメージのダウンロードに必要な秘密キーをコピーします。


docker loginまたはpodman loginを実行し、Oracle Container Registryにログインします。本記事ではpodmanを使用します。UsernameはOracle Account、Passwordは上記でコピーした秘密キーを与えます。

podman login container-registry.oracle.com

% podman login container-registry.oracle.com

Authenticating with existing credentials for container-registry.oracle.com

Existing credentials are invalid, please enter valid username and password

Username: y******@o******.com

Password: ****************

Login Succeeded!

% 


ログインに成功したら、Oracle Graph Quickstart Container Imageをダウンロードします。

podman pull container-registry.oracle.com/database/graph-quickstart:latest

 % podman pull container-registry.oracle.com/database/graph-quickstart:latest

Trying to pull container-registry.oracle.com/database/graph-quickstart:latest...

Getting image source signatures

Copying blob sha256:3ad4f838017096d615ad6be9228656c9c9d21688727c8529f0525018cba6dfd3

Copying blob sha256:5e0746e5292a464df62ac1f048f650692913d88bcd581bf1c9df4fc324499692

Copying blob sha256:712fb8dfcea36ae1c8e27be0d25f62d71f1a051837c720bae7084b858d18ba29

Copying blob sha256:ec52b71cea73d86c6e6aef9f7ed68ba77fb6afe31bb6745804b3f69636304dde

Copying blob sha256:0a72cbf38621774389a72a9fb8f91cc986e1bfc268120ebc70f3e343ed323ef0

Copying blob sha256:101e793fffd2c834e5c7e3e75ec27d6d641387cdbcbd0f3d5420e149c34b0c26

Copying blob sha256:fec50dcb389e9a3c9c9bf3db20e58dc1129ce9217f920f2411ea912110caa2f6

Copying blob sha256:0b70bc5b0c01dd9f62eccef4d2a3c8ff306abcee4ad1893b01978db8ff142cbf

Copying blob sha256:6d29579734df13c8f66fe00e774127d970d307b95997fe0b26cb90995f7529ea

Copying blob sha256:db877435469bb203d326f1b4d3bf5230701197d9a2357dadc5d9bdbf2490b1a0

Copying blob sha256:6fadc6816e4d3bfdf5db7f316dfe325c26b34c221a97cc2c7796534fe8e6b62e

Copying blob sha256:02d4a418ea03e6b2368dcbd060375b4aa5e737a3267b44541e11279834e3fc28

Copying blob sha256:b67bad8260310b107fd1d7a41eb79b81c03ec9d01bd5175773541f7e13e9e538

Copying blob sha256:eed387ac7ded677bdebb0a78929498a985662ca310135292a1aaf530252ae4f7

Copying blob sha256:d1fef6b5edcccba27466fff32626a618bcb1c5765bb08968c67e009368fa2f86

Copying config sha256:8ea691cd93da909eb5aec6e664c8c3eb40ebb2f4f2b8f85262a1d6f4c9abf1f0

Writing manifest to image destination

8ea691cd93da909eb5aec6e664c8c3eb40ebb2f4f2b8f85262a1d6f4c9abf1f0

% 


ダウンロードしたコンテナ・イメージよりコンテナora-graphを作成し、実行します。ORACLE_PWDとして与えたパスワードはSYS、SYSTEMの他にGRAPHUSERのパスワードになります。
  • オプションに-p 7007:7007としてコンテナ内のポート7007をホストの7007にマップしています。Oracle Graph Serverへの接続は7007番ポートに対して実施します。
  • オプションに-p 1521:1521を加えて、コンテナの外からデータベースに接続できるようにしておきます。
  • オプションに-v $PWD:/home/oracle/workを加えて、コンテナとホストの間でデータのやり取りをやり易くしておきます。
podman run -d --name ora-graph -p 7007:7007 -p 1521:1521 -v $PWD:/home/oracle/work -e ORACLE_PWD=<パスワード> container-registry.oracle.com/database/graph-quickstart:latest

% podman run -d --name ora-graph -p 7007:7007 -p 1521:1521 -v $PWD:/home/oracle/work -e ORACLE_PWD=******* container-registry.oracle.com/database/graph-quickstart:latest

1733351fd26b2df0f865dbc69d96fc61931ce9f7a3a84f804155adce315f6925

%


コンテナora-graphが起動したら、ホストのブラウザから以下のURLに接続します。Oracle GraphサーバーはデフォルトでHTTPSが有効になっています。

https://localhost:7007/dash

自己署名証明書によりHTTPSになっているため、警告が表示されます。警告を理解してOracle Graph Serverへのアクセスを許可します。


Oracle Graph Serverへのサインイン画面が表示されます。

UsernamegraphuserPasswordはコンテナ作成時にORACLE_PWDに指定した値を入力します。


Database (SQL Property Graphs)のタブを開き、以下のSELECT文を実行します。
SELECT id_a, id_e, id_b
 FROM GRAPH_TABLE ( BANK_GRAPH
  MATCH (a) -[e]-> (b)
  COLUMNS (vertex_id(a) AS id_a, edge_id(e) AS id_e, vertex_id(b) AS id_b )
) FETCH FIRST 100 ROW ONLY


すごく簡単にOracle Graphを試す環境ができました。

ARM64版が無いのが残念です。

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