X

Technologie - Trends - Tipps&Tricks
in deutscher Sprache

Pluggable Database Lifecycle Management mit Oracle REST Data Service

Marcus Schroeder
Master Principal Sales Consultant

Einleitung

Eine in der modernen Cloud-Welt oft genutzte Schnittstelle stellt die REST-API dar. REST steht für Representational State Transfer und bildet die Abstraktion und Struktur des Verhaltens des World Wide Web ab. Dazu gehören auch Schnittstellen, die den aktuellen Anforderungen der stark auf Services zugeschnittenen technischen IT Landschaft genügen. REST-APIs sind einfach, variable und verwenden gängige Protokolle bzw. Datenformate. So wird oft als Transportprotokoll HTTP/HTTPS und als Datenformat JSON verwendet. Dabei wird REST häufig für die Kommunikation zwischen Systemen (Maschine zu Maschine) verwendet.

Eine zweite Technologie, die sich immer größerer Beliebtheit erfreut ist die Container-Technology. Die stark auf Anwendungsentwicklung und DevOps zugeschnittene Architektur, ermöglicht den einfachen und schnellen Austausch/Kombination von funktionalen Einheiten mittels Container. 

 

Diese beiden genannten innovativen und modernen Technologien unterstützt die Oracle Datenbank seit der Version 12c: Oracle REST Data Service (kurz ORDS) als REST-API und Oracle Pluggable Database als Container Technologie auf Datenbank-Ebene. An dieser Stelle möchte ich noch einmal darauf hinweisen, dass es oft nicht ausreicht eine Datenbank in einem Docker-Container zu betreiben. Für Anwendungs-Komponenten ist der Docker-Container sicherlich der ideale Ort, es sprechen jedoch einige wichtige Gründe dafür, die Datenhaltung in einer geeigneteren Umgebung zu betreiben. Daten-Integrität, Sicherheit, Skalierbarkeit und Ausfallsicherheit sind nur einige dieser Gründe.

Ab der Oracle Datenbank Version 19.1 wird die Steuerung des Pluggable Databases (PDB) Lifecycles durch die Oracle REST-Schnittstelle unterstützt. Durch diesen Baustein ist es jetzt möglich folgende Datenbank-Operationen durch eine REST-API durchzuführen:

  • Anzeigen von Performance (AWR, Top SQL etc.)
  • Überwachen von Session, Locks, Waits etc.
  • Pluggable Databases Lifecycle Aufgaben (Anlegen, Klonen, Löschen etc.)
  • Allgemeine Aufgaben, wie Erstellen, Ändern und Auslesen von Tabellen, Indizes...
  • Durchführen von DB Operationen wie Data Pump, Database Configuration Assistant etc.

Dieser Blog-Artikel behandelt primär den Punkt Pluggable Databases Lifecycle Service. Im folgendem Beispiel wird die Installation, Konfiguration und beispielhafte Nutzung des PDB Lifecycle mittels ORDS dargestellt. Folgende Schritte werden erklärt:

  • ORDS Installation
  • Konfiguration des PDB Lifecycle Managements mit ORDS
  • Nutzung anhand einiger Anwendungsbeispiele

Das Ergebnis ist eine lauffähige Beispiel-Konfiguration, die es ermöglicht schnell und unkompliziert eine Test/Demo-Umgebung aufzubauen.

Bitte beachten: Das folgende Beispiel ist zum Ausprobieren und Testen gedacht. Die REST-Abfragen werden mittels HTTP durchgeführt. Die Übertragung erfolgt dadurch ohne Verschlüsselung. Passwörter und Nutzernamen sind dadurch für Dritte auslesbar! Für erhöhte Sicherheit sollte man mindestens HTTPS konfigurieren. Für eine Produktionsumgebung ist es möglich, viele der aktuellen Sicherheitsrichtlinien zu konfigurieren und die Übertragungswege vom REST-Requester zum ORDS und vom ORDS zur Datenbank abzusichern.

Jeder Oracle User hat seine eigenen Werkzeuge für die Ausführung von SQL-Statements bzw. zum Aufrufen einer REST-API. Folgende Tools wurden in diesem Artikel verwendet:

  • SQL Developer für die SQL-Skripte und DDL/DML-Befehle
  • curl für die REST-Aufrufe
  • Chrome Browser für die Aufrufe des SQL Developer Web (SDW)
  • Terminal für die Installation und Ausführung der Konfiguration

1. ORDS Installation

Die Laufzeitumgebung von ORDS ist eine Web-Anwendung, die auf einem Web-Server läuft. Es werden drei Web-Server-Arten unterstützt: Oracle WebLogic Server , Apache Tomcat und Jetty. Der Jetty-Server ist als Standalone-Variante in der ORDS-Installation integriert. Mittlerweile wird es sogar für produktive Umgebungen unterstützt. Daher verwenden wir in diesem Beispiel den integrierten Jetty-Server. 

Im ersten Schritt laden wir die ORDS Server Software herunter. Die aktuelle Version findet Sie auf http://www.oracle.com/rest. Je nach gewünschter Architektur installiert man die Software direkt auf den Datenbank-Server oder auf einen separaten Server. Welche Variante man wählt ist dem jeweiligen Anwendungsfall geschuldet. In unserem Beispiel wird die Installation direkt auf dem Datenbank-Server durchgeführt. 

Vorsicht: Das Entpacken des ORDS-Zip-Files erfolgt in das gleiche Verzeichnis. Daher ist es ratsam, vorher ein eigenes Verzeichnis für die Installation anzulegen und das File dort zu entpacken. Nach dem Entpacken des Zip-Files wird als Erstes geprüft, ob ORDS bereits in der Datenbank installiert wurde. Die Überprüfung erfolgt mit folgendem Befehl:

java -jar ords.war validate 

Hintergrund: Für das PDB Lifecycle Management muss ORDS in der CDB (im Root Container) installiert werden. Daher sollte man überprüfen, ob schon eine Installation z. B. in einer PDB gibt. Am besten ist es alle Installationen, aus der CDB und den PDBs zu entfernen und danach die aktuelle Version zu installieren. Zum Deinstallieren wird folgender Befehl verwendet:

java -jar ords.war uninstall 

Alle Optionen kann man sich mit folgenden Befehl anschauen:

java -jar ords.war help 

Bild 1: Überprüfung einer bestehenden ORDS-Installation mit validate

Die Installation kann auf zwei verschiedenen Arten durchgeführt werden:

  • Im interaktiven Modus
  • Mittels Silent-Installation

Im interaktiven Modus werden verschiedene Parameter eingegeben. Da z.B. Passwörter mehrmals eingegeben werden müssen, kann dies sehr aufwendig sein. Der "Silent-Install" ist meiner Meinung nach die einfachere Methode, da hier eine Konfigurations-Datei erstellt wird, auf die bei der Installation verwiesen wird. Diese Konfigurations-Datei heißt standardmäßig ords_params.properties. Um diese Datei zu verwenden, müssen nur zwei Parameter angegeben werden.

  • db.servicename - Der Service-Name der Datenbank also nicht die SID.
  • db.serviceNameSuffix - Der Domänenname. Diese Information erhält man über dem Befehl "show parameter db_domain". Sollte der Parameter nicht vorhanden sein, muss er unbedingt gesetzt werden. Die Datenbank muss dazu erneut gestartet werden. Bitte beachten: Vor der DB Domain kommt in dem Parameter ein PUNKT!
db.connectionType=basic
db.hostname=localhost
db.port=1521
db.servicename=<serviceName>
sys.user=SYS
sys.password=PA55wort#-
database.api.admin.enabled=true
database.api.enabled=true
database.api.management.services.disabled=false
db.cdb.adminUser=C##DBAPI_CDB_ADMIN as SYSDBA
db.cdb.adminUser.password=PA55wort#-
dbc.auth.enabled=true
debug.debugger=true
debug.printDebugToScreen=true
feature.sdw=true
jdbc.auth.enabled=true
restEnabledSql.active=true
db.adminUser=test_ords
db.adminUser.password=PA55wort#-
db.password=PA55wort#-
db.serviceNameSuffix=.<dbDomain>
db.username=ORDS_PUBLIC_USER
user.public.password=PA55wort#-
resource.templates.enabled=true
standalone.mode=true
standalone.http.port=8080
standalone.use.https=false
plsql.gateway.add=false
rest.services.ords.add=true

Die detaillierte Erläuterung aller Parameter würde den Rahmen sprengen, daher kann bei Interesse die Dokumentation konsultiert werden. 

Mit den folgenden Befehl kann die ORDS-Installation durchgeführt werden: 

java -jar ./ords.war install --parameterFile /<path2parameterFile>/ords_params.properties simple

Für die Installation muß dann nur noch der gewünschte Pfad, in denen die Konfiguration-Dateien angelegt werden, angegeben werden.

Die Installation startet am Ende den Jetty-Server, dieser muss für die weitere Konfiguration gestoppt werden. Die Konfigurationsparameter werden in der Datei /<path2configDirectory>/default.xml abgespeichert und können bei Bedarf geändert werden.

2. Konfiguration des PDB Lifecycle Management

Nachdem ORDS installiert wurde, werden Änderungen innerhalb der Datenbank durchgeführt, diese sind:

  1. Anlegen eines CDB-Benutzers, der es ermöglicht die PDB-Lifecycle-Prozesse zu steuern
  2. Anlegen eines Benutzers mit DBA-Rechten in der PDB$SEED. Die PDB$SEED wird als Template verwendet, um weitere PDBs zu erzeugen, d.h. alle Einstellungen in diesem Template werden für alle zukünftigen PDBs übernommen. 
  3. REST-Enablen der PDB$SEED. Dadurch kann man sofort auf die REST-API der erstellten PDB zugreifen. Dies dient der einfacheren Bedienbarkeit ist jedoch keine "Pflicht". Wenn es Sicherheitsbedenken gibt, kann man das natürlich auch nach Bedarf manuell für einzelne Objekte machen.

Am Schnellsten geht es, sich mit Standard Common Benutzer wie SYS oder SYSTEM mittels SQL Developer an der CDB anzumelden und folgende Befehle auszuführen:

CREATE USER C##DBAPI_CDB_ADMIN IDENTIFIED BY "PA55wort#-";
GRANT SYSDBA TO C##DBAPI_CDB_ADMIN CONTAINER = ALL;
GRANT DBA TO C##DBAPI_CDB_ADMIN CONTAINER = ALL;
GRANT SYSDBA TO C##DBAPI_CDB_ADMIN CONTAINER = ALL;
GRANT PDB_DBA  TO C##DBAPI_CDB_ADMIN CONTAINER = ALL;
ALTER pluggable database PDB$SEED open read write force;
alter session set container=PDB$SEED;
create user test_ords identified by "PA55wort#-";
grant dba to test_ords;
GRANT PDB_DBA TO test_ords;
GRANT INHERIT PRIVILEGES ON USER SYS TO PUBLIC;
BEGIN 
    ords.enable_schema(p_enabled => TRUE,p_schema => 'TEST_ORDS',p_url_mapping_type => 'BASE_PATH',p_url_mapping_pattern => 'test_ords', p_auto_rest_auth => FALSE); 
    commit;
END;
/

ALTER pluggable database PDB$SEED open read only force;

Mit diesen wenigen Befehlen ist die Konfiguration der Datenbank abgeschlossen. Bei der Ausführung der Prozedur ords.enable_schema darauf achten, das keine Leerzeichen, CR etc. beim Kopieren entstehen!

Bitte unbedingt beachten: Der Wert des Parameters p_url_maping_patter in der ords.enable_schema Prozedur MUSS klein geschrieben werden! Wenn er in Großbuchstaben geschrieben wird, kann die URL nicht mehr aufgelöst werden und man bekommt einen 404-Fehler, nach dessen Ursache man lange suchen kann.

Apropos Routing: Alle REST-Aufrufe, die keiner CDB/PDB zugeordnet werden können, resultieren in einem 404-Fehler. Daraus resultieren dann auch die meisten Konfigurationsfehler! Sollte es zu Problemen kommen, am besten in das Log-File des Jetty-Servers nachschauen, ob es Fehlermeldungen dazu gibt, bzw. noch einmal zentral die Konfigurations-Parameter überprüfen.

 

Im nächsten Schritt werden weitere Parameter im ORDS gesetzt, die das Routing zu den PDBs ermöglichen. 

  1. Setzen der Benutzer und Passwörter für die Pool-Verbindungen für das PL/SQL Gateway, ORDS Data Service RESTful Service und APEX Service Konfiguration.
  2. Setzen des Suffix: Dieser Punkt ist sehr wichtig, ansonsten werden die neu angelegten PDBs nicht gefunden. Um diese Parameter zu ermitteln, sollte als Benutzer sys in der CDB der Befehl "show parameter db_domain" ausgeführt werden. Das Ergebnis wird an den Parameter db.serviceNameSuffix übergeben. WICHTIG!!! der Parameter muss ein Punkt am Anfang haben. Wenn die DB Domain z.B. oracle.com heißt, muss es als Parameter Punkt .oracle.com angegeben werden. Sollte dies nicht erfolgen, kommt wieder der berühmte 404 Fehler und man kann viel Zeit auf die Suche nach der Ursache verbringen!
  3. Anlegen eines Benutzers admin mit dem benötigten Rollen und einem gemeinsamen Passwort (in unserem Fall das bekannte PA55wort#-)
echo db.cdb.adminUser=C##DBAPI_CDB_ADMIN as SYSDBA > cdbAdmin.properties
echo db.cdb.adminUser.password= PA55wort#- >> cdbAdmin.properties
java -jar ords.war set-properties cdbAdmin.properties
java -jar ords.war set-properties --conf default cdbAdmin.properties
java -jar ords.war set-properties --conf apex_rt cdbAdmin.properties
java -jar ords.war set-properties --conf apex_pu cdbAdmin.properties

rm  cdbAdmin.properties

echo db.adminUser=test_ords > pdbAdmin.properties
echo db.adminUser.password= PA55wort#- >> pdbAdmin.properties
java -jar ords.war set-properties --conf default pdbAdmin.properties
java -jar ords.war set-properties --conf apex_rt pdbAdmin.properties
java -jar ords.war set-properties --conf apex_pu pdbAdmin.properties

rm pdbAdmin.properties
echo db.serviceNameSuffix=.<dbDomain> >snsuffix.properties
java -jar ords.war set-properties --conf apex_rt snsuffix.properties
java -jar ords.war set-properties --conf default snsuffix.properties
java -jar ords.war set-properties --conf apex_pu snsuffix.properties
java -jar ords.war user admin "SQL Administrator" "System Administrator" "SQL Administrator" 

Damit ist die Konfiguration vollständig abgeschlossen und wir können Tests durchführen. An dieser Stelle noch ein paar Worte zum REST-Client. Die sicherste Methode für alle REST-Befehle ist die Verwendung des Tools curl allerdings ist die Eingabe und Ausgabe nicht besonders ansprechend zu lesen.

 

Sie erfolgt im allgemeinen in einer Zeile. Man kann sich die Ausgabe zwar in eine Datei umleiten lassen, aber auch diese muss man anschließend zuerst formatieren. Es existieren eine Reihe von REST-Clients in denen die Eingabe/Ausgabe sehr schön aufbereitet ist. Allerdings verstehen viele dieser Clients den Content-Type: application/sql nicht und daher kommt es zu Randeffekten beim Ausführen von REST-Befehlen. Mein Tipp: Ich verwende für alle Befehle, die nicht den Content-Type: application/sql haben, einen der gängigen REST-Clients (in meinen Fall MS Visual Studio Code mit dem REST-Plugin oder Google-Postman) und für den Content-Type application/sql curl. Die Python-Pipe mit dem mjson.tool Parameter gibt den Output in curl besser aufbereitet aus!

Der letzte Schritt der Konfiguration ist das Starten des Jetty-Servers. Um das Starten, Stoppen und die Status-Abfrage einfacher zu gestalten, werden Shell-Skripte verwendet. Diese wurden von Richard Hall entwickelt und können Eins zu Eins übernommen werden. Das Skript muss nur bezüglich des Pfades angepasst werden (ords-Verzeichnis und Log-Verzeichnis)

start_ords.sh

#!/bin/bash
export PATH=/usr/sbin:/usr/local/bin:/usr/bin:/usr/local/sbin:$PATH
export JAVA_HOME=/usr
LOGFILE=/home/oracle/ords/logs/ords-`date +"%Y""%m""%d"`.log
cd /home/oracle/ords
export JAVA_OPTIONS="-Dorg.eclipse.jetty.server.Request.maxFormContentSize=3000000"
nohup $JAVA_HOME/bin/java ${JAVA_OPTIONS} -jar ords.war standalone >> $LOGFILE 2>&1 &
echo "View log file with : tail -f $LOGFILE"

stop_ords.sh

#!/bin/bash
export PATH=/usr/sbin:/usr/local/bin:/usr/bin:/usr/local/sbin:$PATH
kill `ps -ef | grep ords.war | awk '{print $2}'`

status_ords.sh

#!/bin/bash
export PATH=/usr/sbin:/usr/local/bin:/usr/bin:/usr/local/sbin:$PATH
export JAVA_HOME=/usr
ps -ef | grep ords.war

3. Testen des PDB-Lifecycles

An dieser Stelle der wichtige Hinweis: Die URL muss immer das abschließende Zeichen / haben, ansonsten kommt es zu einer Fehlermeldung!

Ausgabe der bestehenden PDBs 

curl -ks -X GET --user admin:PA55wort#- -H "Content-Type: application/json" -k http://<ip-addresse>:8080/ords/_/db-api/stable/database/pdbs/ | python3 -mjson.tool

Bild 2: Ausgabe - Anzeige der bestehenden PDBs. Diese Ausgabe zeigt ausschließlich die existierenden PDBs an, dazu gehört selbstverständlich auch die PDB$SEED. Sollte eine Oracle Standard-Installation verwendet werden, wird hier sicherlich auch die PDB1 auftauchen. Diese kann jedoch gelöscht werden, da wir sie für die weitere Demo nicht benötigen und die PDB1 auch nicht "REST-enabled" ist.

Erstellen einer neuen PDB

Mit dem folgenden REST-Befehl wird eine neue PDB erzeugt. Es gibt eine Anzahl von Parametern, die man für diese PDB einstellen kann. Eine genaue Auflistung ist in der Oracle REST Data Service Dokumentation im Bereich Pluggable Database Lifecycle Management aufgelistet. In diesem Beispiel muss nur die IP-Adresse des ORDS-Servers eingetragen werden.

curl -ks -X POST --user admin:PA55wort#- --data '{
"method": "CREATE",
"adminName": "Admin",
"adminPwd": "PA55wort",
"pdb_name": "PDB2",
"asClone": true,
"fileNameConversions": "NONE",
"unlimitedStorage": true,
"reuseTempFile": true,
"totalSize": "10G",
"tempSize": "100M",
"tdeImport": true,
"tdeKeystorePath": "string",
"tdeSecret": "PA55wort#-",
"getScript": false
}' -H "Content-Type: application/json" -k http://<ip-addresse>:8080/ords/_/db-api/stable/database/pdbs/  | python3 -mjson.tool

Da das Ganze in meinem Beispiel in der Oracle Cloud durchgeführt wurde, mussten die Parameter mit Präfix tde* verwendet werden, da dort TDE per Default aktiviert ist. Ich habe PDB2 als PDB-Namen verwendet, da PDB1 bei der Standard-Installation mit angelegt wird und es ansonsten zu einer Fehlermeldung kommen würde.

Wichtiger Hinweis: Bei Tests hat es sich herausgestellt, daß der Parameter "adminPwd" bei Sonderzeichen im Passwort eine Fehlermeldung erzeugt. Daher ist es besser beim Passwort auf Sonderzeichen zu verzichten. Ich werde dieses Phänomen weiter verfolgen und ggf. diesen Artikel ändern, wenn das Problem gelöst ist.

Löschen einer PDB

Das Löschen einer PDB ist sehr einfach, nur den Namen der PDB angeben und mit dem Parameter action:INCLUDING wird dafür gesorgt, dass die Data-Files der PDB mit gelöscht werden.

curl -ks -X DELETE --user admin:PA55wort#- --data '{"action":"INCLUDING"}' -H "Content-Type: application/json" -k http://<ip-addresse>:8080/ords/_/db-api/stable/database/pdbs/PDB2/ | python3 -mjson.tool

Weitere Befehle für das Klonen, Ändern des Status der PDB etc. können in der API-Dokumentation nachgelesen werden.

4. Weitere Möglichkeiten

In diesem Kapitel werden weitere Demo-Möglichkeiten mit dem ORDS dargestellt. Wenn z.B. mit REST-API-Befehl eine neue PDB erstellt worden ist, kann man mit folgender URL auf den SQL Developer Web zugreifen.

http://<ip-addresse>:8080/ords/sql-developer

Nach Angabe des PDB-Namens des DBA Users (nicht des PDB-Admins) test_ords und des Passwortes öffnet sich der SQL Developer Web (SDW).

Bild 3: SQL Developer Web

Im SDW kann man zum Beispiel im SQL-Bereich schnell eine CSV-Datei hochladen und diese dann über einen REST-API-Aufruf abrufen. In meinem Beispiel habe ich eine kleine CSV-Datei hochgeladen (SQL > Data Loading). Vorsicht bei der Einstellung der Trennzeichen der CSV-Datei: Diese stehen per Default auf Komma!

Die Tabelle hat den Namen channels_error und kann ohne weitere Konfiguration direkt mit folgenden REST-API-Befehl abgerufen werden:

curl -ks -X POST --user TEST_ORDS:PA55wort#- --data-binary "select * from channels_error;" -H "Content-Type: application/sql" -k http://<ip-addresse>:8080/ords/PDB2/test_ords/_/sql | python3 -mjson.tool

Bild 4: Auslesen der Tabelle channels_error

Fazit

Das Verwenden der REST-API für PDB Lifecycle Management macht richtig Spaß. Das Anlegen einer PDB dauert nur wenige Sekunden und man benötigt keinerlei Oracle-Client oder sonstige spezifische Konfigurationen. Wer in seiner modernen DevOps-Umgebung nicht auf die Vorteile einer Oracle Datenbank verzichten möchte ist mit dieser Lösung gut beraten. Die Oracle DB kann dabei in allen Deployment-Arten installiert werden, ob Single-Instanz, RAC oder MAA. Die ORDS Schnittstelle funktioniert unabhängig von der gewählten Architektur- On-Premises oder in der Cloud.

Weiterführende Links

ORDS Einstiegs-Seite: http://www.oracle.com/rest

Englische Beschreibung ORDS PDB Lifecycle Management: https://www.linkedin.com/pulse/cicd-complete-lifecycle-management-oracle-database-its-luca-bindi/?articleId=6679301433784852480

Auflistung aller Artikel zum Thema ORDS von Richard Hall: https://oracle-base.com/articles/misc/articles-misc#ords

Und natürlich die Blog-Seite des SQL Developer & ORDS Product Managers Jeff Smith: https://www.thatjeffsmith.com/oracle-rest-data-services-ords/

 

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.