AS400 legge tutti i database

Un AS400 per domare tutti i database

Proprio così, an AS400 to rule them all, dove “them” sono tutti i database relazionali che hanno un driver JDBC che, come spiegherò in seguito, possiamo utilizzare persino con il linguaggio RPG.

Alzi la mano chi lavora su IBM i / AS400 e ha avuto la necessità, almeno una volta, di utilizzare un database relazionale esterno (MySQL, PostgreSQL, Oracle, Microsoft SQL Server, etc). A me è capitato moltissime volte e immagino sia lo stesso per altri.

Le necessità sono varie:

  • migrazione da o verso un altro ERP
  • aggiornare un database esterno ad esempio quello di una soluzione di Business Intelligence esterna all’AS400
  • leggere informazioni dal database di un’applicazione esterna (esempio una webapp) da elaborare nel proprio ERP su AS400
  • etc

Anche le modalità per farlo sono varie:

  • web services
  • soluzioni ETL (Extract Tansform Load), come ad esempio Pentaho Data Integration, sviluppando e schedulando i job che leggono le informazioni dai database esterni e le scrivono in tabelle su AS400 o viceversa
  • accesso diretto dall’AS400!!!

Quest’ultima è la modalità di cui voglio scrivere in quest’articolo, ovvero la possibilità di accedere a database esterni all’AS400 tramite driver JDBC usando SQL e, udite udite, il vecchio “obsoleto” e tanto caro RPG.

Per far questo ci viene in aiuto il tool AppServer4RPG di Dieter Bender, che ci permette di utilizzare direttamente dall’AS400 qualunque database abbia un driver JDBC, ovvero quelli già citati prima: MySQL, MariaDB, PostgreSQL, Oracle, Microsoft SQL Server, DB2 e tanti altri.

Nell’esempio che descrivo di seguito accedo da un AS400 in Italia al database PostgreSQL presente su un server Linux in Francia.

Configurazione AppServer4rpg

Innanzitutto bisogna scaricare e decomprimere appserver4rpg.

Spostare sull’AS400 via FTP il file jvagate.savf e ripristinare la libreria JVAGATE dal SAVF col comando RSTLIB.

Rinominare la cartella precedentemente decompressa con il nome JVAGATE quindi spostarla nella root dell’IFS dell’AS400: /JVAGATE (ATTENZIONE: se avete la necessità di darle un altro nome basta che lo indichiate nell’area dati AS4RPGPATH della libreria precedentemente ripristinata).

Copiate in /JVAGATE/lib/ tutti i driver JDBC che vi servono (se non li avete cercateli e scaricateli da internet). Nel mio caso ho scaricato e copiato il driver JDBC di PostgreSQL: postgresql-42.1.1.jar

A questo punto bisogna modificare il file di configurazione /JVAGATE/lib/global.properties per indicare i riferimenti di ogni database esterno da raggiungere.

Nel mio caso ho aggiunto i riferimenti del mio database PostgreSQL:

ard.url.PGDWS=jdbc:postgresql://xxx.xxx.xxx.xxx:5432/dws
ard.driver.PGDWS=org.postgresql.Driver

dove

  • PGDWS: è il nome di fantasia che utilizzerò successivamente nel comando ADDRDBDIRE
  • url: è la stringa di connessione al database in cui “xxx.xxx.xxx.xxx” va sostituito con l’IP o l’hostname del database server e dws è il nome del database a cui voglio connettermi
  • driver: è l’indicazione di quale driver utilizzare per la connessione (quello riferito al JDBC driver precedentemente copiato nel percorso /JVAGATE/lib/)

I parametri sopra descritti sono quelli essenziali per definire la connessione, ma, oltre ad essi, si possono aggiungere altri parametri facoltativi. Tra questi ne segnalo due:

ard.properties.PGDWS.user=mIo-UtentE
ard.properties.PGDWS.password=Mia-PassWord

Questi due parametri ci permettono di definire l’utente e la password con cui viene fatta la connessione al database. Indicandoli nel file global.properties si evita di indicarli ad ogni connessione fatta da STRSQL o da RPG, ma soprattutto permettono di aggirare il problema delle connessioni con utente minuscolo. In pratica, quando viene fatta la CONNECT al database, l’AS invia sempre l’utente in MAIUSCOLO anche se lo indicate minuscolo (compreso indicarlo tra apici). In questo caso l’unico modo che ho trovato per aggirare il problema è indicare l’utente all’interno del file di configurazione global.properties.

Avviare il servizio su AS:

SBMJOB CMD(CALL PGM(JVAGATE/STRJVAGATE)) JOB(JVAGATE) JOBQ(QCTL)

ATTENZIONE: se si aggiunge un nuovo database al file global.properties o un nuovo JDBC driver è necessario riavviare il servizio su AS400.

Infine si aggiunge una voce all’indirizzario RDB che si riferisca a quanto configurato nel precedente file:

ADDRDBDIRE RDB(PGDWS) RMTLOCNAME(*ARDPGM) ARDPGM(JVAGATE/JDBCGATE)

Finalmente si può accedere al database esterno

Test con STRSQL

Accesso diretto tramite il tool STRSQL dell’AS400.

Connessione al database:

CONNECT TO PGDWS USER mio-utente USING 'Mia-PassWord'

ATTENZIONE: come descritto in precedenza, se l’utente del database è minuscolo, vi darà errore di connessione perchè l’AS lo passa sempre in maiuscolo. In questo caso dovete indicare utente e password all’interno del file di configurazione global.properties e di conseguenza non è necessario specificarli nell’istruzione CONNECT.

Esecuzione di qualunque istruzione SQL, ad esempio:

select id_zona3, cod_zona3, desc_zona3
from zone
where cod_zona3 like 'IT%'
limit 100;

risultato:

SQL AS400

Disconnessione dal Database

rollback
DISCONNECT CURRENT

Test con RPG

Ora vediamo come accedere al database esterno direttamente da un programma RPG.

Il sorgente dev’essere ovviamente di tipo SQLRPGLE.

Di seguito il sorgente di un semplice esempio in cui ci si connette al database e si legge una tabella con SQL:

H DECEDIT('0,') DATEDIT(*DMY.)                                   
*--------------------------------------------------------------*
D sql_stm         S         32700                              
*                                                              
D S_ID           S             9 0 INZ                        
D S_COD           S             6   INZ                        
D S_DESC         S             40   INZ                        
*                                                              
D USR             S             10   inz('mio-utente')              
D PWD             S             10   inz('Mia-PassWord')          
*--------------------------------------------------------------*
/free                                                          
  Exec Sql CONNECT TO PGDWS USER :USR USING :PWD;              
                                                               
  sql_stm = 'select +                                          
    id_zona3, cod_zona3, desc_zona3 +                          
    from zone +                                            
    where cod_zona3 like ''IT%'' +                            
    limit 20';                                                
                                           
  Exec Sql Prepare SPG from :sql_stm;    
  Exec Sql Declare CPG cursor for SPG;    
                                           
  Exec Sql Open CPG;                      
/end-free                                  
*                                          
C                   DO       *HIVAL        
C/EXEC SQL                                  
C+ FETCH CPG INTO :S_ID, :S_COD, :S_DESC    
C/END-EXEC                                  
C                   if       SqlCod<>0    
C                   leave                  
C                   endif                  
*                                          
/free                                      
    // mostro le info lette dal DB esterno
    dsply ('ID:     ' + %char(S_ID));      
    dsply ('Codice: ' + %char(S_COD));    
    dsply ('Desc.: ' + %char(S_DESC));    
    dsply ('---------------------------------------');            
/end-free                                                        
*                                                                
C                   ENDDO                                          
*                                                                
/free                                                            
  Exec Sql Close CPG;                                            
  Exec Sql ROLLBACK;                                            
  Exec Sql DISCONNECT CURRENT;                                  
/end-free                                                        
C                   SETON                                       LR
*--------------------------------------------------------------*      

ATTENZIONE: compilare il sorgente con le seguenti opzioni:

  • COMMIT(*CS)
  • OPTION(*SQL)

Risultato dell’esecuzione:

RPG AS400

Altri esempi li ha forniti il buon Dieter Bender nella cartella JVATEST.LIB che trovate nel file decompresso all’inizio.

Note particolari

Logging

Questo tool genera log molto verbosi in /JVAGATE/logs/. Di default genera un file log per ogni giorno e NON elimina i file dei giorni precedenti. Se lo utilizzate in modo massiccio vi troverete presto con GigaByte di log.

Per evitare questo problema si possono introdurre delle politiche di Log Rotation un po’ più stringenti modificando il file di configurazione /JVAGATE/conf/log4j.properties.

Commentare le due istruzioni indicate sotto e aggiungere le nuove istruzioni con le vostre preferenze:

...
# VERSIONE ORIGINALE (genera un file di log per ogni giorno ... SENZA LIMITI)
#log4j.appender.MeinDaRoFiAppender=org.apache.log4j.DailyRollingFileAppender
#log4j.appender.MeinDaRoFiAppender.datePattern='.'yyyy-MM-dd
# Versione con Log Rotation basato sulla dimensione e con numero di file limitato
log4j.appender.MeinDaRoFiAppender=org.apache.log4j.RollingFileAppender
log4j.appender.MeinDaRoFiAppender.MaxBackupIndex=20
log4j.appender.MeinDaRoFiAppender.MaxFileSize=10MB
...

dove:

  • MaxBackupIndex indica il numero massimo di file di log da tenere
  • MaxFileSize indica la dimensione massima di ogni file

quindi, con i parametri sopra indicati, i log occuperanno al massimo 10MB per 20 file, ovvero 200MB.

Proprietà STRSQL

Quando ci si connette ad un database esterno usando STRSQL viene automaticamente modificato un attributo della sessione, Convenzione di denominazione, che da *SYS diventa *SQL. Questo fa si che quando vi disconnettete e provate ad usare l’SQL con le altre tabelle dell’AS400 si comporterà in modo diverso da come siete abituati, ad esempio, non vedrà più la lista librerie, quindi se fate una SELECT senza specificare la libreria cercherà la tabella in una libreria con nome uguale al nome dell’utente (ulteriori dettagli sulle differenze tra SYS e SQL li potete trovare spiegati bene qui: https://blog.faq400.com/it/database-db2-for-i/naming-sys-vs-sql/).

Per ripristinare l’impostazione standard è sufficiente premete F13, scegliete l’opzione 1. Modifica attributi sessione e ripristinare la convenzione *SYS come da immagine seguente:

Conclusione

Come avrete intuito leggendo l’articolo, l’accesso ad un database relazionale esterno tramite driver JDBC è semplicissimo anche dall’AS400. Non resta che sfruttarlo 😉

Un ringraziamento particolare va a Dieter Bender che ha sviluppato questo comodo tool e l’ha rilasciato sotto licenza open-source GPLv2. Thanks Dieter.

(Letto 292 volte di cui 89 negli ultimi 30gg)
twitterlinkedinmailby feather

4 thoughts to “Un AS400 per domare tutti i database”

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

*

code