Oracle Forms Server 10g

Oracle Forms Server 10g e' il componente dell'architettura di Oracle Application Server 10g che si occupa dell'esecuzione di applicazioni di data entry (Forms) realizzate con Oracle Developer.
Con Developer vengono realizzate, in modo molto veloce e con molteplici possibilita' di controllo, applicazioni Forms agganciando campi e blocchi a colonne e tabelle in una base dati Oracle. Tali applicazioni possono poi essere utilizzate in modalita' Client/Server (nelle precedenti releases) o su Web. Nel primo caso si tratta di una normale applicazione Client/Server che richiede l'installazione dell'ambiente di runtime di Oracle sul Client e la sua configurazione (eg. TNSNAMES.ORA). In questo documento viene analizzata con maggior dettaglio l'architettura utilizzata quando si vogliono pubblicare le applicazioni Forms su web. La versione di riferimento in questo documento e' OAS 10g (9.0.4) ma sono riportate le differenze rispetto alle versioni precedenti e sucessive quando necessario.

Architettura

I componenti che e' necessario analizzare per comprendere l'architettura del Forms Server sono tre:

Oracle Forms Architecture

La sequenza di attivazione di un'applicazione e' descritta nei passi seguenti.
Dal browser (eg. Internet Explorer) viene richiamato l'URL iniziale dell'applicazione. Tipicamente si tratta di un URL del tipo http:/hostname.domain:port/forms90/f90servlet?config=XX dove XX corrisponde ad una sezione del file di configurazione $ORACLE_HOME/forms/server/formsweb.cfg.
La richiesta, attraverso la Web Cache, raggiunge l'OHS (Oracle HTTP Server che e' un Apache) che, attivando il servlet sull'OC4J, restituisce il contenuto della pagina iniziale. Tale pagina contiene un Applet e viene pertanto attivata una Java Virtual Machine (JVM) nel browser. Le prime versioni della JVM disponibili su Windows presentavano alcuni problemi, percio' fino alla versione Java 1.3 veniva utilizzata una specifica JVM realizzata da Oracle: JInitiator. Attualmente [dal 2009 JInit non e' piu' supportato] viene utilizzata la versione standard Java JSE di Sun/Oracle.
L'applet prende il controllo e richiede l'attivazione di un servlet sull'Application Server. In OAS le servlet sono ospitate su JVM denominate Oracle Container for Java (OC4J). La servlet attiva un processo per ogni connessione Client. Il processo lanciato e' f90webm che realizza la business logic dell'applicazione. Tale logica e' il risultato della programmazione in Form e viene contenuta in forma compilata su file *.FMX.

A questo punto la fase di caricamento e' terminata ed inizia l'esecuzione del Forms. Il processo f90webm implementa la logica applicativa:

Il dialogo tra f90webm e l'Applet avviene con un tunnel HTTP.

All'interno dell'architettura di OAS il Forms Server risiede sempre sui sistemi di Mid Tier. Dal punto di vista tecnico la componente di Infrastructure non viene utilizzata se non nel caso di autenticazione con SSO.

Dal punto di vista delle connessioni al DB ogni utente connesso a Forms utilizza una sesione Oracle. E' molto semplice ottenere l'elenco degli utenti SQL*Forms connessi (ed anche il modulo FMX utilizzato) con:

SELECT sid, serial#, to_char(logon_time,'YYYY-MM-DD HH24:MI:SS'), client_identifier,
       username, module, status, machine, seconds_in_wait, program
  FROM gv$session
 WHERE program like 'frmweb%'
 ORDER BY logon_time;

Tutto chiaro vero? Ma se volete maggiori dettagli continuate a leggere...

Amministrazione

Dal punto di vista di amministrazione del prodotto non vi sono indicazioni particolari. La console dell'Enterprise Manager di OAS permette di gestire ogni aspetto.

Enterprise Manager - Forms status

Il motore del Forms e la sua architettura sono comunque ben consolidati e robusti. Quindi terminata la fase di startup e tuning iniziale del sistema non sono generalmente necessari interventi specifici.
Poiche' l'architettura prevede un numero notevole di processi e' molto importante monitorarne l'attivita' per evitarne una crescita non controllata. Parametri non corretti di disconnessione possono far raggiungere i limiti del sistema ospite con conseguenti blocchi del servizio.

Installazione

Oracle Forms Server e' uno dei molteplici componenti dell'ambiente di OAS - Oracle Application Server. Di conseguenza l'installazione del Forms Server e' semplicemente annegata all'interno dell'istallazione dei componenti di Middle Tier di OAS. Vi sono diverse scelte per l'installazione di un Mid Tier... ma tutte contengono il Forms Server!

Una possibilita' introdotta di recente (dalla 9.0.4 che e' la prima release denominata 10g) e' quella dell'installazione di un Forms+Report Server senza richiedere un'istanza OAS di Infrastructure (configurazione Standalone).

Configurazioni particolari

Una volta installato Forms puo' essere utilizzato immediatamente e la sua configurazione e' adatta a decine di applicazioni e fino ad un centinaio di utenti. Anzi, la configurazione di default utilizza parecchi processi, thread, ... per un normale ambiente di sviluppo o di test conviene ridurne il numero per non appesantire inutilmente il sistema.
Come tutte le applicazioni Oracle anche il Forms, per collegarsi al DB server, legge il file sqlnet.ora e quindi, a seconda della configurazione, determina i dati per la connessione al DB Server dall'OID o dal tnsnames.ora.

Nel caso di un numero molto elevato di utenti o in altre condizioni particolari una soluzione e' quella di utilizzare piu' island di OC4J per distribuire il carico. L'utilizzo di piu' island e' vantaggioso anche su un server singolo poiche' l'architettura del Forms Server sfrutta meglio i sistemi multiprocessore.

L'autenticazione degli utenti utilizzata dai Forms e' quella standard sull'RDBMS Oracle. E' tuttavia possibile utilizzare alternativamente l'SSO per la fase di login degli utenti (ML Note 199072.1). Con la versione 10g le possibilita' di configurazioni sono diverse e l'integrazione e' maggiore (eg. gestione dell'expiration delle password). Naturalmente per poter utilizzare l'SSO e' necessaria un'installazione standard di OAS che preveda l'istanza di infrastruttura.

Storia e versioni

Le applicazioni Forms sono presenti nella storia di Oracle fino dalle prime versioni. Le prime implementazioni richiedevano la compilazione di una serie di file e realizzavano applicazioni character oriented. Dalla versione 4.5 di SQL*Forms e' possibile il deploy delle applicazioni su web.

La versione 6i (agganciata alla versione corrispondete di Developer) e' ancora molto utilizzata poiche' e' l'ultima che supporta la modalita' a carattere e l'utilizzo in Client/Server.

Un notevole cambiamento architetturale si e' avuto con la 9i (eg. 9.0.2). Anziche' in modo nativo come avveniva con la versione 6 il dialogo avviene verso un servlet con protocollo HTTP (nella 6i era possibile scegliere tra connessione socket ed HTTP). Questo ha consentito un piu' semplice deploy (eg. nessun problema con i Firewall) ma ha anche introdotto problemi prestazionali se utilizzato in rete con elevata latenza a causa del numero maggiore di messaggi scambiati tra il Client e l'Application Server.

Nella versione OAS 10g (9.0.4) l'ambiente Forms e' disponibile come default nell'installazione dell'ambiente Mid Tier (eg. BI+Portal). Dalla stessa versione e' inoltre possibile un'installazione dei soli componenti Form e Report Server senza utilizzare un server per i servizi di Infrastruttura (configurazione Standalone).
Sempre con OAS 10g l'ambiente di sviluppo e' contenuto nella Oracle Developer Suite 10g.

Nella versione OAS 10g Release 2 (10.1.2.0.0) l'ambiente Forms non era inizialmente disponibile ma e' stato rilasciato con la 10.1.2.0.2. I cambiamenti rispetto alla 9.0.4 non sono molti (eg. f90web -> frmweb) ed e' fornito un tool per la migrazione automatica. Questa versione e' quella utilizzata dall'ERP di Oracle: Oracle eBusiness Suite R12.

Per finire Oracle E-Business Suite utilizza moltissimo applicazioni Forms...

Tutto chiaro? Non penso, non ho capito bene neanche io! Nella tabella seguente provo a riportare le relazioni tra Forms Server, Oracle Application Server ed Oracle eBusiness Suite:
FormsOASEBS
Oracle Forms 6i (6.0)Oracle 9iAS Rel 1 (1.0.2)11i (11.5.x)
Oracle Forms 9i (9.0.2) Oracle 9iAS Rel 2 (9.0.3)
Oracle Forms 10g (9.0.4) Oracle Application Server 10g (9.0.4)
Oracle Forms 10g Rel 2 (10.1.3) Oracle Application Server 10g Rel 2 (10.1.2.0.2) R12 (12.x)

E' anche importante l'incrocio di certificazione con tutti i componenti dell'architettura (eg. client, browser, JInitiator/JRE, SO, ...). Su questo l'unico riferimento possibile e' la documentazione ufficiale.

Upgrade

Dovete effettuare un upgrade dei vostri Form? Nessun problema... o meglio, non e' poi cosi' complesso.
La documentazione Oracle e' molto completa, ma se siete dei praticoni... Continuate a leggere!

Una volta escluse le funzionalita' non piu' presenti nelle versioni attuali (utilizzo a carattere e/o in modalita' Client/Server), e' possibile provare ad aprire le vecchie Form con il nuovo Developer. Funziona nella maggioranza dei casi. Se si sono utilizzati packages PL/SQL non piu' presenti e' nessaria una conversione manuale. Comodo e' questo caso il Migration Assistant utilizzabile in modalita' batch (sintassi Unix):

for i in `ls *.fmb`
do
   frmplsqlconv.sh module=$i
done
oppure in modalita' wizard (sintassi Windows):
SET FORMS_PATH=%ORACLE_HOME%\forms
Start menu -> ORACLE_HOME -> Forms Developer -> Oracle Forms Migration Assistant (GUI Mode)
Oppure: frmplsqlconv.bat mode=wizard. Naturalmente si puo' anche lanciare il wizard su Unix ed il batch su Windows...

I successivi paragrafi sono un poco piu' tecnici... meglio smettere qui.
Non ho resistito a non mettere qualche pettegolezzo, quindi siete avvertiti: Lasciate ogni speranza o voi che leggete!

Debug & Trace

Sono disponibili diversi livelli di trace e logging su tutti, o quasi, i componenti. In caso di crisi... vediamo come abilitarli tutti con il massimo dettaglio!

Per attivare il logging sul web server e' necessario agire sul file $ORACLE_HOME/Apache/Apache/conf/httpd.conf ed inserire la direttiva LogLevel debug nella sezione iniziale. Il log viene riportato nel file $ORACLE_HOME/Apache/Apache/log/error_log. Il valore utilizzato in una configurazione normale e' warn.

Per attivare il logging sul container e' necessario agire sul file $ORACLE_HOME/j2ee/OC4J_BI_Forms/config/server.xml ed inserire la direttiva <global-thread-pool min="20" max="40" queue="80" keepAlive="600000" debug="true"/> nella sezione relativa. Il log viene riportato nel file $ORACLE_HOME/j2ee/OC4J_BI_Forms/log/default-web-access.log. Il valore utilizzato in una configurazione normale e' false.

Risolto il problema... non dimenticate di togliere il debug!

Internal

Bene... ora prendiamo un bisturi e facciamo un po' di studio di anatomia!
Naturalmente quanto segue vale per una versione specifica di Forms (ho utilizzato la 9.0.4) su un sistema operativo Unix (ho utilizzato un Red Hat EL 3.4) e ho raccolto un po' di altre informazioni che non ho inserito nei capitoli precedenti... Se operate in altri ambienti le cose cambiano un poco ma la logica e' sempre la stessa (eg. se avete un server MS al posto dell'eseguibile f90webm avrete ifweb90.exe ma... auguri!!)

Per lanciare una form e' possibile utilizzare il link http://hostname.domain[:port]/forms90/html/runform.htm che presenta una serie di simpatiche opzioni... Oppure il solito http://hostname.domain[:port]/forms90/f90servlet?form=XX
La prima volta che viene utilizzato un Form deve essere scaricato ed installato un Plug-in per il browser. Si tratta della Java Virtual Machine (JVM) mantenuta da Oracle che prende il nome di JInitiator e con una versione specifica corrispondente al Forms Server (eg. con OAS 10g Forms Services 9.0.4.1 JInitiator e' in 1.3.1.18). I browser piu' recenti utilizzano Java in modo nativo o come plug-in. Le versioni di Java hanno introdotto nel tempo sempre maggiori controlli di sicurezza. Il richiamo del JInitiator e' in HTML standard 4.0 quindi utilizza i TAG OBJECT o EMBED e non piu' l'obsoleto APPLET. Con i nuovi tag vi sono diverse possibilita' nell'indicare le versioni di oggetti... Puo' essere utile saperlo se cambiate versione ed avete migliaia di utenti!
Se si utilizza Jinitiator, se utilizza l'HTTPS e si utilizza una Root CA non censita va aggiornato manualmente il file certdb.txt (c:\program files\oracle\jinitiator version\lib\security).

Naturalmente la richiesta arriva alla Web Cache che la passa identica al web server Apache. Poiche' vi e' una direttiva (contenuta nel file $ORACLE_HOME/forms90/server/forms90.conf richiamato dall'httpd.conf) che reindirizza le richieste all'OC4J_BI_Forms ogni volta che l'URL path inizia con /forms90, Apache richiama via AJP l'OC4J corrispondente.
Il Java Container e' quello realizzato da Orion (OC4J) ed e' un container J2EE standard... Quindi la sua configurazione si trova su server.xml. I servlet ospitati dal container Java che ospita il forms sono due: f90servlet ed l90servlet. Il primo si occupa di generare la corretta richiesta sul client per richiamare una form. Puo' quindi essere attivato inizialmente ma non svolge altra attivita'. Path e parametri passati al lancio dell'applicazione da parte dell'f90servlet sono contenuti nel file $ORACLE_HOME/forms90/server/formsweb.cfg. Nel caso di utilizzo di JInitiator il servlet f90servlet indichera' al browser di carircare l'Applet: http://hostname.domain[:port]/forms90/java/f90all_jinit.jar.
Il secondo servlet e' un "listener" sempre attivo per tutta la sessione utente con un thread java allocato. Il dialogo avviene su HTTP 1.1 ma, se un qualche componente nella catena verso il client non e' in grado di supportarlo (eg. un vecchio proxy server), si passa alla versione 1.0 del protocollo. I principali parametri (eg. destroy.timeout session.useCookies session.checkFrequency) sono contenuti nel file $ORACLE_HOME/forms90/server/forms90.properties. l90servlet si occupa di attivare un processo unix f90webm che e' quello che implementa la logica applicativa del Forms. Quindi gestisce ogni comunicazione passandogli ogni messaggio che arriva dal client e restituendo la risposta... Tra il thread ed il processo sono "aperte" una serie di connessioni sia su socket che in pipe.

Come architettura di processi anche il Forms Server segue la "normale" struttura di OAS. Il padre di tutti i processi, che si occupa anche del controllo, dell'eventuale riavvio, ... e' opmn. Da questo dipende il processo (o i processi se abbiamo piu' island) OC4J container. Naturalmente si tratta di una JVM. Da questo dipendono una serie di thread (eg. 50) per l'esecuzione dei servlet ed infine ai processi f90webm. L'associazione e' 1:1:1:1. Un utente, un servlet listener, un processo f90webm, una connessione Net* al DB Oracle. Quindi con 1000 utenti ci sono 1000 servlet thread, 1000 f90webm, 1000 connessioni Net*: meglio pensare ad utilizzare piu' island OC4J e l'MTS... ma non divaghiamo!
Data la genealogia i vari processi ereditano caratteristiche da genitori, nonni e bisavoli... Questo vale anche per i limiti sul sistema (ulimit), file aperti, ... che risultano identici in cascata su tutti i processi.
Se le risorse di sistema sono ampie e ben dimensionate... non c'e' nessun problema. I passaggi sono molti e la potenza di calcolo richiesta al server e' significativa... attenzione quindi al dimensionamento del mid-tier. Se invece si raggiunge qualche limite di sistema (eg. nfile, uproc) puo' capitare un po' di tutto! In questi casi non e' certo facile effettuare il troubleshooting... meglio prevenire con settaggi abbondanti dei parametri del kernel.

Ed il bisturi?

[root@hostname]# ps -efaw | grep f90w
orias    24495 24494  0 10:34 ?        00:00:00 /oracle90/mid10g/bin/f90webm server webfile=HTTP-0,0,0,default,192.168.0.1
orias     8818  8817  1 11:46 ?        00:00:00 /oracle90/mid10g/bin/f90webm server webfile=HTTP-0,0,0,default,10.102.194.62

--> Per ogni sessione Forms vi e' un processo f90webm che, bonta' Oracle, riporta anche
    l'IP del client! La presenza dell'IP e' comodissima per la gestione!!!


[root@hostname]# ps -efaw | grep 24494
orias    24494 16496  0 10:34 ?        00:00:00 /oracle90/mid10g/jdk/bin/java -server -Djava.security.policy=/oracle90/mid10g/j2ee/OC4J_BI_Forms/config/java2.policy -Djava.awt.headless=true -Xmx512M ...

--> Il processo f90webm e' figlio di un thread java che sta eseguendo l'l90servlet


[root@hostname]# lsof -p 24495
COMMAND   PID  USER   FD   TYPE      DEVICE     SIZE       NODE NAME
f90webm 24495 orias  cwd    DIR         8,5     4096    1476447 /oracle90/mid10g/forms90
f90webm 24495 orias  rtd    DIR         8,2     4096          2 /
f90webm 24495 orias  txt    REG         8,5 10993952    1087668 /oracle90/mid10g/bin/f90webm
f90webm 24495 orias  mem    REG         8,2   495474     356957 /lib/ld-2.2.4.so
f90webm 24495 orias  mem    REG         8,5   318671     324854 /oracle90/mid10g/lib/libiplsn.so.0
...
f90webm 24495 orias  mem    REG         8,2   262396     357004 /lib/libnss_files-2.2.4.so
f90webm 24495 orias  mem    REG         8,5    14980    1476454 /oracle90/mid10g/forms90/test.fmx
f90webm 24495 orias    0r  FIFO         0,0          2897544365 pipe
f90webm 24495 orias    1w  FIFO         0,0          2897544366 pipe
f90webm 24495 orias    2w  FIFO         0,0          2897544367 pipe
f90webm 24495 orias    3r   REG         8,5    18944     730145 /oracle90/mid10g/forms90/mesg/fmcus.msb
f90webm 24495 orias    4r   REG         8,5    12288    1200645 /oracle90/mid10g/guicommon9/tk90/mesg/uius.msb
f90webm 24495 orias    5u  IPv4 -1390422924                 TCP hostname.domain:47831->hostname.domain:47832 (ESTABLISHED)
f90webm 24495 orias    6r   REG         8,5    50176     730146 /oracle90/mid10g/forms90/mesg/fmfus.msb
f90webm 24495 orias    7r   REG         8,5   439296      48726 /oracle90/mid10g/rdbms/mesg/oraus.msb
...
f90webm 24495 orias    9u  IPv4 -1392912924                 TCP hostname.domain:47833->infra.domain:3060 (ESTABLISHED)
f90webm 24495 orias   10u  IPv4 -1419022924                 TCP hostname.domain:47839->dbserver.domain:1521 (ESTABLISHED)

--> f90webm e' un eseguibile Unix che esegue il programma OCI f90webm, mappa in memoria le normali
    librerie Unix ed Oracle... mappa in memoria anche il file FMX contenente la FORM da interpretare
    ha le pipe di std/in/out/err aperte (lo std/in e' in w sul thread l90servlet) ...
    la prima connessione TCP e' verso il listener servlet, quindi 
    con l'autenticazione utente, apre la connessioni Net* verso l'RDBMS Oracle.
    E... avete notato la sessione LDAP con l'infrastruttura?
    Serve per "trovare" la stringa di connessione e/o effettuare su OID l'autenticazione.

--> Il numero di connessioni dell'OC4J che ospita l'l90servlet e' molto elevato...

Qualche altro dettaglio?

Provate a seguire il traffico di rete tra client e web server con un analizzatore di rete o uno sniffer...
Troverete un fracco di messaggi in tunnel HTTP. Su questo c'e' poco da dire se non che la dimensione dei messaggi e, soprattutto, il numero e' maggiore rispetto a quanto avveniva con la connessione socket (quella utilizzata in 6i). Questo non e' un problema se non nel caso di connessioni con una latenza elevata in cui il rallentamento puo' essere significativo e va meglio analizzata l'architettura...

Provate a seguire in debug o con un truss (il comando dipende dal dialetto Unix, puo' essere anche: strace, tusc, ...) i processi f90webm ed i java container...
Troverete una catena di passaggi di dati non cosi' semplice da seguire (soprattutto con Java che esegue piu' thread). Tra client, web cache, Apache, servlet listener ed f90webm i dati scambiati sono tutti pacchetti HTTP... Mentre da f90webm partono anche le richieste via Net* all'RDBMS Oracle che funge da DB Server.

Se infine tutto questo non vi basta... leggete la documentazione ufficiale Oracle!


Testo: Oracle Forms Server 10g
Data: 15 Maggio 2005
Versione: 1.0.5 - 31 Giugno 2010
Autore: mail@meo.bogliolo.name