2024年2月28日水曜日

Oracle Container RegistryにあるOracle Database FreeとORDSのイメージからOracle APEXの環境を作成する - macOS編

Oracle Container Registryに登録されているDatabaseのfree(Oracle Database 23c Free)のイメージとords(Oracle REST Data Services (ORDS) with Application Express)から、Oracle APEXの環境を作成します。

Intel MacのmacOS Sonama 14.3.1のpodmanを使います。

macOSでのpodmanの準備については、以前の記事「Autonomous Database Free Container ImageをmacOS上で実行する」を参照してください。以降の手順は、podmanの仮想マシンが起動済みであることが前提です。

あらかじめコンテナのイメージをダウンロードしておきます。

podman pull container-registry.oracle.com/database/free:latest
podman pull container-registry.oracle.com/database/ords:latest

コンテナ・イメージがダウンロードされていることを確認します。

podman images

% podman images

REPOSITORY                                   TAG         IMAGE ID      CREATED      SIZE

container-registry.oracle.com/database/ords  latest      a848f4190472  2 weeks ago  2.01 GB

container-registry.oracle.com/database/free  latest      7510f8869b04  2 weeks ago  8.73 GB

%


Oracle Database FreeのコンテナとOracle REST Data Servicesのコンテナを実行するpodを作成します。名前はapexとします。

podman pod create -p 8181:8181 -p 1521:1521 --name apex

% podman pod create -p 8181:8181 -p 1521:1521 --name apex

82e49fa7bb76332aca6f55c909eaea53c689b0b7b038c6c18c485c8a6166179f

%


podの作成を確認します。

podman pod ls

% podman pod ls

POD ID        NAME        STATUS      CREATED         INFRA ID      # OF CONTAINERS

82e49fa7bb76  apex        Created     28 seconds ago  91b3ef1ee9a4  1

% 


Oracle Database Freeのコンテナを作成し実行します。コンテナの名前はapexdbとします。

podman run -d --pod apex --name apexdb -e ORACLE_PWD=<SYSのパスワード> container-registry.oracle.com/database/free:latest

% podman run -d --pod apex --name apexdb -e ORACLE_PWD=******** container-registry.oracle.com/database/free:latest

f8f2c56d7f0441cb381e136827faa5acdc84b8b7a8058f8014a1536967a08ac2

% 


コンテナapexdbが起動し、ステータスがhealthyであることを確認します。

podman ps

% podman ps            

CONTAINER ID  IMAGE                                               COMMAND               CREATED             STATUS                       PORTS                                           NAMES

91b3ef1ee9a4  localhost/podman-pause:5.0.3-1715299200                                   2 minutes ago       Up About a minute            0.0.0.0:1521->1521/tcp, 0.0.0.0:8181->8181/tcp  82e49fa7bb76-infra

f8f2c56d7f04  container-registry.oracle.com/database/free:latest  /bin/bash -c $ORA...  About a minute ago  Up About a minute (healthy)  0.0.0.0:1521->1521/tcp, 0.0.0.0:8181->8181/tcp  apexdb

% 


ORDSのコンテナの構成に必要なディレクトリを準備します。macOSの場合、ords_configにホストのディレクトリをマウントしても権限の問題があり、ORDSのコンテナから構成ファイルを書き込むことができません。そのため、ords_configにマウントするディレクトリは準備しません。

mkdir ords_secrets
chmod 777 ords_secrets 

% mkdir ords_secrets

% chmod 777 ords_secrets


ords_secrets以下にファイルconn_string.txtを作成します。SYSのパスワードはコンテナapexdbを作成する際に環境変数ORACLE_PWDとして設定した値です。また、この文字列はDBに接続する以外にもORDSを構成する際に与える情報としても使われるため、ホスト名:ポート番号/サービス名の書式である必要があります。ポート番号1521は必須です。

echo 'CONN_STRING=sys/パスワード@localhost:1521/freepdb1' > ords_secrets/conn_string.txt

% echo 'CONN_STRING=sys/パスワード@localhost:1521/freepdb1' > ords_secrets/conn_string.txt

 


ORDSのコンテナを作成します。

podman run --pod apex --name ords -v `pwd`/ords_secrets/:/opt/oracle/variables container-registry.oracle.com/database/ords:latest

初回起動時はAPEXのインストールが行われます。

% podman run --pod apex --name ords -v `pwd`/ords_secrets/:/opt/oracle/variables container-registry.oracle.com/database/ords:latest

INFO : This container will start a service running ORDS 24.1.0 and APEX 23.2.0.

INFO : CONN_STRING has been found in the container variables file.

INFO : Database connection established.

INFO : Apex is not installed on your database.

INFO : Installing APEX on your DB please be patient.

INFO : You can check the logs by running the command below in a new terminal window:

       docker exec -it apex tail -f /tmp/install_container.log

WARN : APEX can be installed remotely on PDBs, If you want to install it on a CDB,

       install it directly on the Database and not remotely.



APEXのインストール状況を確認するコマンドは、以下になります。

podman exec -it ords tail -f /tmp/install_container.log

% podman exec -it ords tail -f /tmp/install_container.log


--application/pages/page_00067

--application/pages/page_00069

--application/pages/page_00070

--application/pages/page_00071

--application/pages/page_00073

--application/pages/page_00075

--application/pages/page_00076

--application/pages/page_00077


しばらくするとAPEXのインストールが完了します。

INFO : APEX has been installed.

INFO : Configuring APEX.

INFO : APEX_PUBLIC_USER has been configured as oracle.

INFO : APEX ADMIN password has configured as 'Welcome_1'.

INFO : Use below login credentials to first time login to APEX service:

       Workspace: internal

       User:      ADMIN

       Password:  Welcome_1


APEXのインストールが完了するとORDSの構成が開始し、こちらも完了します。

java.class.version=55.0


2024-05-13T02:17:01.210Z WARNING     *** jdbc.InitialLimit in configuration |default|lo| is using a value of 10, this setting may not be sized adequately for a production environment ***

2024-05-13T02:17:07.775Z INFO        


Mapped local pools from /etc/ords/config/databases:

  /ords/                              => default                        => VALID     



2024-05-13T02:17:07.885Z INFO        Oracle REST Data Services initialized

Oracle REST Data Services version : 24.1.0.r1080942

Oracle REST Data Services server info: jetty/10.0.20

Oracle REST Data Services java info: Java HotSpot(TM) 64-Bit Server VM 11.0.15+8-LTS-149



以上で以下のURLより、ORDSおよびAPEXにアクセスできるようになりました。



APEXにアクセスすると、日本語リソースがインストールされていないことが確認できます。


日本語リソースをインストールします。幸いなことにORDSのコンテナ・イメージには言語りソースが含まれていました。

podman exec -it ords sh

 % podman exec -it ords sh

sh-4.4$ 


APEXが展開されているディレクトリへ移動し、SQLclでデータベースに接続します。

cd /opt/oracle/apex/23.2.0
export PATH=/opt/oracle/sqlcl/bin:$PATH
sql sys/パスワード@localhost/freepdb1 as sysdba

sh-4.4$ cd /opt/oracle/apex/23.2.0

sh-4.4$ export PATH=/opt/oracle/sqlcl/bin:$PATH

sh-4.4$ sql sys/************@localhost/freepdb1 as sysdba



SQLcl: Release 24.1 Production on Mon May 13 02:22:49 2024


Copyright (c) 1982, 2024, Oracle.  All rights reserved.


Connected to:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.4.0.24.05


SQL> 


日本語リソースをインストールします。

@load_trans JAPANESE

SQL> @load_trans JAPANESE


PL/SQL procedure successfully completed.


Installing Oracle APEX translation - JAPANESE



. ORACLE

.

. Application Express Hosted Development Service Installation.

..............................................................


PL/SQL procedure successfully completed.


--application/set_environment

API Last Extended:20231031

Your Current Version:20231031

This import is compatible with version: 20231031

COMPATIBLE (You should be able to run this import without issues.)

ID offset during import: 0

New ID offset for application: 0



しばらくすると日本語リソースのインストールが完了します。

...done

Adjust instance settings


PL/SQL procedure successfully completed.


SQL> 


日本語リソースのインストールが完了すると、APEXで日本語を選択できるようになります。

管理者ユーザーはADMIN、初期パスワードはWelcome_1です。

初回サインイン時に新規パスワードを設定する必要があります。


以上でAPEXの環境作成は完了です。

作成しているpodの起動や停止は以下のコマンドで実行します。

podman pod stop apex
podman pod start apex

Oracle Container Registryにあるコンテナ・イメージを使ったOracle APEXの環境構築の方法は以上になります。

2024年2月16日金曜日

オラクルの公式ブログMulti Level Expense Approval using APEX Workflowのワークフローを理解する

Oracle CorporationでAPEXワークフローを開発しているAnanya Chatterjeeさんが、オラクルの公式ブログに以下の記事を寄稿しています。

Multi Level Expense Approval using APEX Workflow

Ananya ChatterjeeさんはOracle APEXの承認タスクの開発も行なっています。APEXワークフローがリリースされる前のAPEXで、承認タスクによる多段階承認の実装を紹介する記事も書かれています。

Implementing Multi-Approvals in Oracle APEX 22.1
https://blogs.oracle.com/apex/post/implementing-multi-approvals-in-oracle-apex-221

承認タスクを使った多段階認証の実装については、本ブログでも以下の記事で紹介しています。

APEX 22.1の承認コンポーネント(4) - 多段階承認の実装

Oracle APEX 23.2からAPEXワークフローが提供されたため、承認タスクによる多段階承認の記事に以下のコメントが追記されました。
Note: With the availability of Workflow feature in APEX 23.2 release, it is now possible to visualize and design multi-level approvals in a more declarative manner, which you can read about in another blog. This blog is still relevant if you are looking to use using Approval Components, standalone, without Workflow and is also relevant for pre 23.2 versions of APEX.

APEX 23.2以降あれば、多段階承認はAPEXワークフローで実装することを推奨していると言えます。

以下より、ブログ記事「Multi Level Expense Approval using APEX Workflow」で作成しているワークフローで、多段階承認をどう実装しているのか説明しようと思います。ワークフローを組み込んだアプリケーションは、元記事の手順にそって作業を行うことで作成できます。英語ですが、手順が具体的でコードおよびスクリーンショットも揃っていることから、作業はそれほど難しくありません。

本記事では、ワークフローを以下のように若干簡素にしています。電子メールの送信アクティビティを削除し、ワークフロー終了に接続しています。


以下より、多段階承認のワークフローを確認していきます。

最初に経費精算の承認ワークフローを開始します。

ユーザーSTEVEでサインインし、経費申請を行います。以下の画面で重要なパラメータはExpense Amount、つまり費用です。


費用はページ・アイテムP4_EXPENSE_AMOUNTに入力されます。


ボタンSUBMITを押すと、経費精算のワークフロー(定義はExpense Reimbursement Workflow)が開始します。


ワークフロー・パラメータAmountにページ・アイテムP4_EXPENSE_AMOUNTの値を割り当てています。ワークフロー・パラメータはワークフローの開始時に値が設定され、開始後は値を変更することはできません。経費精算の承認処理を行なっている間に、申請した費用が変更されたら困ります。経費申請の申請者や費用といった、ワークフローの処理中に変更できない値をワークフロー・パラメータとして設定します。


ワークフローExpense Reimbursement Workflowを確認します。

ワークフロー・パラメータとしてAmountが設定されています。このパラメータにページ・アイテムP4_EXPENSE_AMOUNTの値が設定されます。ワークフローの中でこのパラメータは静的IDAMOUNTより参照します。

Oracle APEXでは、ページ・アイテムアプリケーション・アイテムの値をバインド変数置換文字列として参照できますが、その際はページ・アイテムやアプリケーション・アイテムの名前を指定します。ワークフローのワークフロー・パラメータおよびワークフロー・バージョン変数は名前の代わりに静的IDを指定して参照します。


ワークフローが開始すると、最初にアクティビティCompute Max Levelが実行されます。このアクティビティでは以下のPL/SQLコードが実行されます。
declare
    level_no number;
begin
    if :AMOUNT < 500 then
        level_no := -1;
    elsif :AMOUNT < 1000 then
        level_no := 1;
    elsif :AMOUNT < 5000 then
        level_no := 2;
    else
        level_no := 3;
    end if;
    :MAX_LEVEL := level_no;
end;
申請した費用が500より少なければMAX_LEVEL-11000より少なければ 15000より少なければ 2、それ以上は 3 を設定しています。

表APPROVAL_LEVELSに、以下のシード・データが挿入されています。
insert into APPROVAL_LEVELS values (10, 'JANE', 'jane@expenseteam.com', 1);
insert into APPROVAL_LEVELS values (20, 'MATT', 'martin@expenseteam.com', 1);
insert into APPROVAL_LEVELS values (30, 'BO', 'bo@expenseteam.com', 2);
insert into APPROVAL_LEVELS values (40, 'CLARA', 'clara@expenseteam.com', 2);
insert into APPROVAL_LEVELS values (50, 'SUSIE', 'susie@expenseteam.com', 3);
このワークフローでは、費用が500より少なければ自動承認、1000より少なければ承認レベル(表APPROVAL_LEVELSの列LEVEL_CODEの値)が1であるJANEかMATTが承認が必要、1000以上5000未満ではさらに承認レベルが2であるBOかCLARAの承認が必要、それ以上はさらに承認レベルが3であるSUSIEの承認が必要、という承認フローを実装しています。


MAX_LEVELワークフロー・バージョン変数として作成されています。


続く切替えApproval Needed?では、ワークフロー・バージョン変数MAX_LEVEL-1であれば自動承認としてワークフローを終了させ、それ以外(1か2か3)であれば、ヒューマン・タスクを生成するアクティビティCreate Approved Requestへ進みます。


アクティビティCreate Approval Requestでは、承認タスクReimbursement Requestを作成します。承認タスクの結果はワークフロー・バージョン変数TASK_OUTCOMEに設定され、後続の切替えApproved?により参照されます。承認タスクの結果はAPPROVEDまたはREJECTEDです。


承認タスクReimbursement RequestのパラメータにLevel Noがあります。Level Noには、ワークフロー・バージョン変数CURRENT_LEVELが割り当てられています。


ワークフロー・バージョン変数CURRENT_LEVELには、タイプ静的値静的値として1が設定されています。ワークフロー・バージョン変数はアクティビティによって変更できるため、この値は初期値またはデフォルト値になります。


承認タスクReimbursement Requestのタスク定義では、潜在的所有者SQL問合せが設定されています。
select mgr_name from approval_levels where level_code = :LEVEL_NO
パラメータLEVEL_NOにはアクティビティCreate Approval Requestが呼び出された時点でのワークフロー・バージョン変数CURRENT_LEVELの値が割り当てられて、承認タスクが作成されます。つまりCreate Approval Requestの初回呼び出し時はCURRENT_LEVELは初期値のなので、LEVEL_NOになります。

結果として費用が500以上の経費申請(自動承認の対象にならない経費申請)は、最初に承認レベルが1のJANEかMATTのどちらかの承認を必要とします。


JANEかMATTが承認タスクを承認すると、切替えApproved?を経由して切替えAll Approvals Completed?へ進みます。

反対に承認タスクを却下すると、切替えRejected At First Level?に進みます。


切替えAll Approvals Completed?では、ワークフロー・バージョン変数CURRENT_LEVELと比較する切替えタイプが設定されています。タイプCheck Workflow Variableでは、実際の条件は切替えから伸びている接続に設定されます。


切替えAll Approvals Completed?とアクティビティIncrement Levelの接続No条件として&MAX_LEVEL.より小さいが設定されています。申請した費用が4000のときはMAX_LEVELが2なのでCURRENT_LEVELより小さいため、こちらの接続が選択されます。

それ以外、つまりMAX_LEVELCURRENT_LEVELが同じ値であれば、経費申請が承認されてワークフローは終了します。


アクティビティIncrement Levelでは以下のPL/SQLコードが実行されます。ワークフロー・バージョン変数CURRENT_LEVELに1が加算されます。
begin
:CURRENT_LEVEL := :CURRENT_LEVEL+1;
end;
その後、アクティビティCreate Approval Requestが呼び出されます。アクティビティCreate Approval Requestにて作成される承認タスクの潜在的所有者はパラメータLEVEL_NO、つまりワークフロー・バージョン変数CURRENT_LEVELで決まります。CURRENT_LEVEL2の場合、承認レベルがのBOかCLARAの承認が必要になります。


JANEかMATTが承認タスクを却下した場合は、切替えRejected at First Level?に進みます。この切替えは条件として、CURRENT_LEVEL1であれば経費申請を却下してワークフローを終了します。

JANEかMATTが経費申請を承認し、次の承認レベルのBOからCLARAにより経費申請が却下されるとCURRENT_LEVELは2になるため、アクティビティReset Levelに進みます。


アクティビティReset Levelでは以下のPL/SQLコードを実行し、CURRENT_LEVELに戻しています。
begin
:CURRENT_LEVEL := 1;
end;
つまり経費申請の承認は、承認レベルが1のJANEとMATTの承認から取り直しになります。


以上が、ブログ記事Multi Level Expense Approval using APEX Workflowで実装しているワークフローの説明になります。

今回の説明に使用したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/expense-reimbursement.zip

ワークスペースへのユーザー作成を避けるため、以下のPL/SQLファンクションによるカスタム認証をカレント・スキームにしています。
function demo_authentication (
    p_username in varchar2,
    p_password in varchar2 )
    return boolean
is
begin
    if upper(p_username) in (
        'STEVE','JANE','BO','SUSIE','CLARA'
    ) then
        return true;
    end if;
    return false;
end;

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