[OCI]AWS LambdaのファンクションをAutonomous DatabaseからSQLファンクションとして呼び出してみた

# はじめに

先日の機能追加で、AWS LambdaのファンクションをAutonomous DatabaseからSQLファンクションとして呼び出すことができるようになりました。

AWS LambdaのファンクションをSQLファンクションとして呼び出すには、DBMS_CLOUD_FUNCTIONパッケージを使用して設定を行います。

今回は、AWS Lambdaにデフォルトで用意されている「Hello World」を「HelloWorld」という名前のファンクションとしてデプロイし、AWS Lambdaの「HelloWorld」ファンクションをAutonomous DatabaseからSQLファンクションとして呼び出してみました。

OCI FunctionsのファンクションをAutonomous DatabaseからSQLファンクションとして呼び出す場合の記事はこちら。

https://qiita.com/500InternalServerError/items/ac17dbd10ec887301dc5

なお、今回はadminユーザとしてAutonomous Databaseに接続して検証を行いました。

# 1.クレデンシャルの作成

DBMS_CLOUD.CREATE_CREDENTIALプロシージャで、DBMS_CLOUD_FUNCTIONパッケージで使用するクレデンシャルを作成します。

クレデンシャルAWS_CREDをAWS IAMユーザのアクセスキー、シークレットアクセスキーを使用して作成します。
※クレデンシャルの作成に使用するAWS IAMユーザには、予め適切なポリシーを割り当てておきます。
```
SQL> BEGIN
  2    DBMS_CLOUD.CREATE_CREDENTIAL (
  3      credential_name => 'AWS_CRED',
  4      username        => 'XXXXXXXXXXXXXXXXXXXX', -- AWS IAMのアクセスキー
  5      password        => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -- AWS IAMのシークレットアクセスキー
  6    );
  7  END;
  8* /

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

SQL>
```

# 2. ファンクションのカタログの作成 
DBMS_CLOUD_FUNCTION.CREATE_CATALOGプロシージャを使用して、ファンクションのカタログを作成します。
ここでは、クレデンシャルとして1.で作成したAWS_CREDを使用して、cloud_paramsで指定したリージョン内にあるAWS Lambdaのファンクションを含むカタログAWS_DEMO_CATALOGを作成しています。

```
SQL> BEGIN
  2      DBMS_CLOUD_FUNCTION.CREATE_CATALOG (
  3          credential_name  => 'AWS_CRED', 
  4          catalog_name     => 'AWS_DEMO_CATALOG', 
  5          service_provider => 'AWS',
  6          cloud_params     => '{"region_id":"ap-northeast-1"}' -- AWSのリージョン識別子
  7      );
  8  END;
  9* /

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

SQL> 
```
USER_CLOUD_FUNCTION_CATALOGビューで、ユーザのファンクションカタログに関する情報を確認できます。
```
SQL> SELECT * FROM user_cloud_function_catalog;

CATALOG_NAME        CLOUD_PROVIDER    
___________________ _________________ 
AWS_DEMO_CATALOG    AWS               

SQL> 
```
# 3. カタログの同期
DBMS_CLOUD_FUNCTION.SYNC_FUNCTIONSプロシージャを使用して、カタログAWS_DEMO_CATALOGのスコープ内にあるAWS Lambdaのファンクションに対するPL/SQLラッパーを作成します。
```
SQL> BEGIN
  2     DBMS_CLOUD_FUNCTION.SYNC_FUNCTIONS (
  3         catalog_name => 'AWS_DEMO_CATALOG'
  4     );
  5  END;
  6* /

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

SQL> 
```
USER_CLOUD_FUNCTIONビューで、ユーザの外部ファンクションに関する情報を確認できます。
```
SQL> SELECT * FROM user_cloud_function;

CATALOG_NAME        APPLICATION_ID    CLOUD_FUNCTION_NAME    FUNCTION_NAME    FUNCTION_ID                                                       
___________________ _________________ ______________________ ________________ _________________________________________________________________ 
AWS_DEMO_CATALOG                      HelloWorld             HELLOWORLD       arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:HelloWorld    

SQL> 
```

# 4. カタログの内容の確認
DBMS_CLOUD_FUNCTION.LIST_FUNCTIONSプロシージャを使用して、カタログAWS_DEMO_CATALOGの内容を確認します。

```
SQL> VAR function_list CLOB;
SQL> 
SQL> BEGIN
  2      DBMS_CLOUD_FUNCTION.LIST_FUNCTIONS (
  3         credential_name  => 'AWS_CRED', 
  4         catalog_name     => 'AWS_DEMO_CATALOG',
  5         function_list    => :function_list);
  6  END;
  7* /

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

SQL> 
SQL> SELECT JSON_QUERY(:function_list, '$' RETURNING VARCHAR2(32676) pretty) AS search_results FROM dual;

SEARCH_RESULTS                                                                                                                                                                                                                              
___________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ 
[
  {
    "functionName" : "HelloWorld",
    "functionArn" : "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXX:function:HelloWorld",
    "invokeEndpoint" : "https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.lambda-url.ap-northeast-1.on.aws/"
  }
]    

SQL> 
```
ファンクションHelloWorldがカタログAWS_DEMO_CATALOGに登録されていることが確認できました。

# 5. Autonomous DatabaseからAWS Lambdaのファンクションを実行

以下のSQLでAWS LambdaのファンクションHelloWorldを実行します。

```
SQL> SELECT helloworld('') as response
  2* FROM dual;

RESPONSE                                                     
____________________________________________________________ 
{"STATUS":"200","RESPONSE_BODY":"\"Hello from Lambda!\""}    

SQL>
```
AWS Lambdaのファンクションを実行し、ファンクションの実行結果を取得できることが確認できました。

以上で、AWS LambdaのファンクションをAutonomous DatabaseからSQLファンクションとして呼び出せることが確認できました。

# 参考情報
・[Invoke User Defined Functions](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/user-defined-functions-autonomous.html#GUID-8E002919-CA8A-418D-B66D-0F5B8B719D3A)
・[DBMS_CLOUD_FUNCTION Package](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/dbms-cloud-function.html#GUID-0720B3D6-D92C-4179-9A92-4B22008597E8)