X

Technologie - Trends - Tipps&Tricks
in deutscher Sprache

DBMS_CLOUD REST APIs

Möchte man programmatisch - beispielsweise mit PL/SQL - im Oracle Cloud Object Storage zum Beispiel einen Bucket anlegen, löschen oder Compartments auflisten, kann man dies jetzt auch mit der REST-API Erweiterung des Package DBMS_CLOUD bewerkstelligen. Dabei liefert die DBMS_CLOUD REST-API nicht nur eine Schnittstelle für die Oracle Cloud Infrastruktur (OCI), sondern auch für Amazon Web Services oder Azure Cloud.

Übrigens für diejenigen, die APEX nutzen: Mit APEX Version 19.2 gibt es eine Integration für Oracle Cloud Infrastructure Web Credentials, um mit Oracle Cloud Object Storage zu arbeiten. Möchte man mehr dazu erfahren, kann man dazu folgenden Artikel von Adrian Png im Oracle Magazine finden: Better File Storage in Oracle Cloud. Dort wird ausführlich beschrieben, wie man einfach mit den REST-APIs des Oracle Cloud Object Storage in APEX interagieren kann.

Aber zurück zu DBMS_CLOUD - wozu hat man DBMS_CLOUD eigentlich bisher verwendet? Die Packages DBMS_CLOUD und DBMS_CLOUD_ADMIN bieten wichtige Schnittstellen und Erweiterungen für das Arbeiten mit Autonomous Database. Mit wachsender Funktionalität der Autonomous Database werden auch diese Packages erweitert. Im Handbuch im Abschnitt Autonomous Database Supplied Package Reference kann man Details zu den einzelnen Funktionen und Prozeduren nachlesen.

Folgende Liste zeigt einige Beispiele für Funktionen und Prozeduren von DBMS_CLOUD:

- COPY_DATA zum Kopieren von Dateien aus dem Object Storage in Autonomous Database 
- CREATE_CREDENTIAL, DROP_CREDENTIAL, UPDATE_CREDENTIAL
  zum Speichern, Löschen und Ändern von Cloud Object Storage Credentials
- CREATE_EXTERNAL_TABLE (CREATE_ETXERNAL_PART_TABLE, CREATE_HYBRID_PART_TABLE)
  zum Erzeugen von External Tables (auch partitioniert bzw. hybrid) für Dateien in der Cloud
VALIDATE_EXTERNAL_TABLE (VALIDATE_EXTERNAL_PART_TABLE, VALIDATE_HYBRID_PART_TABLE)
  Validieren der External Table
- DELETE_FILELIST_FILES Löscht bzw. listet Dateien in dem angegebenen Verzeichnis
DELETE_OBJECT,  LIST_OBJECTS Löschen und Auflisten von Objekten aus dem Cloud Objekt Storage
- GET_OBJECT Listet Objekte aus dem Object Storage und kopiert sie in Autonomous Database
- PUT_OBJECT Kopiert eine Datei aus der Autonomous Database in den Cloud Object Storage 

Wie kann man nun programmatisch mit DBMS_CLOUD einen Bucket im Objektstore anlegen? Das Ganze funktioniert in zwei Schritten:

  1. Authentifizierung gegenüber dem Cloud Objekt Store mit DBMS_CLOUD.CREATE_CREDENTIALS
  2. Verwendung der REST API mit DBMS_CLOUD.SEND_REQUEST 

Da es sich hierbei um "native" Oracle Cloud Infrastructure Operationen handelt, müssen die Credentials OCI spezifische Parameter wie User OCID, Tenancy OCID, privater Key und Fingerprint enthalten. Folgendes Beispiel zeigt eine Verwendung.
Hinweis: Bitte unbedingt beachten, dass beim Kopieren und Einfügen des Private Keys keine zusätzlichen Umbrüche oder Sonderzeichen entstehen.

-- Löschen des Credentials execute dbms_cloud.drop_credential('CRED_USEXTEND'); -- Anlegen des Credentials begin DBMS_CLOUD.CREATE_CREDENTIAL ( credential_name => 'CRED_USEXTEND',  user_ocid       => 'ocid1.user.oc1..aaaaaaaajjo6ll3nsokpwdxxxxxxxxxxxxxxxxxxrijhbjxq', tenancy_ocid    => 'ocid1.tenancy.oc1..aaaaaaaap7sgxxxxxxxxxx343ztr6ydz6fscx6nuka', private_key     => '-----BEGIN RSA PRIVATE KEMIIEpAIBAAKCA..-----END RSA PRIVATE KEY-----', fingerprint    => '9c:3f:d2:5b:49:1b:20:92:4e:4a:5d:cc:d7:d4:c1:66'); end; /

Hinweis: Informationen zur Generierung eines Private/Public Key Paares und Fingerprints erhält man im Abschnitt How to Generate an API Signing Key aus der OCI Dokumentation. Nach der Erzeugung kann man die Credentials wie üblich mit ALTER DATABASE in der Datenbank bekanntgeben.

alter database property set default_credential = 'ADMIN.CRED_USEXTEND';

Alle Credentials lassen sich mit DBA_CREDENTIALS auflisten.

select credential_name, enabled, comments from dba_credentials;

CREDENTIAL_NAME ENABLED COMMENTS
--------------- ------- -------------------------------------------------------------------------
CREDENTIAL_US1  TRUE    {"comments":"Created via DBMS_CLOUD.create_credential"}
CREDENTIAL_US2  TRUE    {"comments":"Created via DBMS_CLOUD.create_credential"}
CRED_US         TRUE    {"comments":"Created native credential via DBMS_CLOUD.create_credential"}
CRED_USEXTEND   TRUE    {"comments":"Created native credential via DBMS_CLOUD.create_credential"}

Im nächsten Schritt wird die Funktion SEND_REQUEST des Package DBMS_CLOUD mit folgenden Parametern verwendet.

DBMS_CLOUD.SEND_REQUEST (
credential_name IN VARCHAR2, -- hier CRED_USEXTEND
uri             IN VARCHAR2, -- passende URI, die zum Request passt
method          IN VARCHAR2, -- HTTP Methode GET, PUT, POST, HEAD, DELETE mit DBMS_CLOUD
headers         IN CLOB DEFAULT NULL, -- Headers der Cloud native API in JSON Format
body            IN BLOB DEFAULT NULL) -- Body des PUT oder POST Request in JSON Format
RETURN DBMS_CLOUD_TYPES.resp;

Die Informationen zur verwendeten URI findet man in der OCI Dokumentation im Kapitel APIs and Endpoints - in unserem Fall unter Objectstorage im Abschnitt CREATE BUCKET. Es handelt sich; um den Endpoint https://objectstorage.eu-frankfurt-1.oraclecloud.com und die Methode POST /n/{namespaceName}/b/. Der Body erfordert die Übergabe des neuen Bucket Namens 'name' und der Compartment ID 'compartmentId'. Somit sieht das Anlegen eines Buckets mit Namen TESTUS folgendermaßen aus:


DECLARE
  resp DBMS_CLOUD_TYPES.resp;
BEGIN
  resp := DBMS_CLOUD.send_request(
  credential_name => 'CRED_USEXTEND',
  uri             => 'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/oraseemeadesandbox/b/',
  method          => DBMS_CLOUD.METHOD_POST,
  body            => UTL_RAW.cast_to_raw(
            JSON_OBJECT('name' value 'TESTUS',
                        'compartmentId' value 'ocid1.compartment.oc1..aaaaaaaaz77ryqv6xwxxxxa'))); 
END;
/

Den Erfolg kann man danach einfach in der graphischen Cloud Konsole im Bereich Object Storage überprüfen.

Um den Bucket wieder zu löschen, reicht folgender Aufruf aus. Die DELETE Methode erfordert außer dem Credentialnamen und der URI keine weiteren Informationen. Das folgende Beispiel löscht den Bucket TESTUS wieder.

DECLARE
  resp DBMS_CLOUD_TYPES.resp;
BEGIN
  resp := DBMS_CLOUD.send_request(
  credential_name => 'CRED_USEXTEND',
  uri    => 'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/oraseemeadesandbox/b/TESTUS',
  method => DBMS_CLOUD.METHOD_DELETE);
END;
/

Auch hier kann man das Ergebnis natürlich wieder in der Cloud Konsole überprüfen.

Im letzten Beispiel listen wir alle Compartments auf. Dazu wird die GET Methode mit DBMS_CLOUD.METHOD_GET verwendet. Die Endpoints, URIs und die entsprechenden Parameter findet sich in der Identity and Access Management Service API. Der Endpoint lautet hier https://identity.eu-frankfurt-1.oraclecloud.com/ und die Methode ist GET /20160918/compartments/. Sie erfordert die Information über die Root Compartment ID. Die Header Informationen bestehen aus einem JSON Objekt mit Wert 'list-compartments' für die 'opc-request-id'. Der vollständige Aufruf sieht dann folgendermaßen aus.

SET SERVEROUTPUT ON
DECLARE
  DBMS_CLOUD_TYPES.resp;
  root_compartment_ocid VARCHAR2(512) := 'ocid1.tenancy.oc1..aaaaaaaap7sg74i4ibhxz7ymmvxxxxxka';
BEGIN
  resp := DBMS_CLOUD.send_request(
  credential_name => 'CRED_USEXTEND',
  uri     => 'https://identity.eu-frankfurt-1.oraclecloud.com/20160918/compartments?compartmentId='||
              root_compartment_ocid,
  method  => DBMS_CLOUD.METHOD_GET,
  headers => JSON_OBJECT('opc-request-id' value 'list-compartments'));
  dbms_output.put_line('Body: ' || DBMS_CLOUD.get_response_text(resp));
END;
/

Die Ausgabe ist im JSON Format und gibt ausführliche Informationen über die Inhalte der Compartments. Ein Ausschnitt aus dem Ergebnis sieht dann so aus:

body: [ {
  "id" : "ocid1.compartment.oc1..aaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxhfv2a",
  "compartmentId" : "ocid1.tenancxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxa",
  "name" : "AutonomousPlatform",
  "description" : "AutonomousPlatform ",
  "timeCreated" : "2019-07-24T11:17:24.350Z",
  "freeformTags" : { },
  "definedTags" : {
    "Operation" : {
      "CreationDate" : "2019-07-24T11:17:24.289Z",
      "CreatedBy" : "ocid1.saml2idp.oc1..aaaaaaaaq7g335nqsjimza3xpib67lribjdzadesisqjaywawvkww3tlpuvq/marcus.schroeder@oracle.com"
    }
  },
  "lifecycleState" : "ACTIVE"
}, {
  "id" : "ocid1.compartment.oc1..aaaaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxg5qkrdbix56q",
  "compartmentId" : "ocid1.tenancxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxa",
  "name" : "BI",
  "description" : "Compartment for the BI Group",
  "timeCreated" : "2018-12-07T11:16:32.630Z",
  "freeformTags" : { },
  "definedTags" : { },
  "lifecycleState" : "ACTIVE"
}, { ...

Detaillierte Informationen und Beispiele zur DBMS_CLOUD REST API finden sich entweder im Oracle Autonomous Data Warehouse Handbuch im Kapitel DBMS_CLOUD REST APIs oder im Oracle Autonomous Transaction Processing Handbuch im Kapitel DBMS_CLOUD REST APIs.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.