RPG (Report Program Generator) è un linguaggio di programmazione proprietario creato da IBM, maturo e affidabile e utilizzato da molti anni prettamente per applicazioni di carattere economico/finanziario. Realizziamo e pubblichiamo un web service che richiama una procedura scritta in linguaggio RPG su architettura IBM AS400/iSeries.
Introduzione
Grazie ai web services, che sono i pilastri portanti dell’architettura SOA, è possibile garantire un livello di integrazione sempre maggiore tra ambienti eterogenei e di conseguenza ampliare la visibilità di procedure scritte precedentemente per architetture tradizionalmente conosciute come “chiuse”. Nello specifico creeremo un web service scritto in Java pubblicato sull’application server WebSphere in grado di chiamare un programma AS400/iSeries RPG.
Lo strumento di sviluppo e le risorse necessarie
Come strumento di sviluppo utilizzeremo ASTK (Application Server Toolkit) basato sulla tecnologia Eclipse. ASTK anche se viene considerato fondamentalmente uno strumento di assemblaggio per la pubblicazione e il testing delle applicazioni su WebSphere può essere utilizzato anche per lo sviluppo di applicazioni Java EE. Per l’interazione con la macchina AS400/iSeries ci appoggeremo a librerie messe a disposizione dal Toolbox Java di IBM, ovvero una raccolta di classi Java che consentono di accedere ai dati e alle risorse presenti sui sistemi AS400/iSeries. Nel nostro esempio utilizzeremo la versione Open Source del Toolbox conosciuta con il nome JTOpen che attualmente è arrivata alla versione 6.0.
La logica applicativa
La business logic è rappresentata da una procedura RPG (si veda il codice sottostante) che, a fronte di due parametri di input (rispettivamente la data e il codice del fondo di investimento), restituisce il valore unitario di quest’ultimo.
************************************************************************ FTAFUCPL1 IF E K DISK RENAME(RECTAFU:RecQuote) ************************************************************************ * c *entry plist c parm fondo 10 c parm valuta 8 c c parm quota 10 /free KFONDO=fondo; KDATA=%INT(valuta); VQUOTA=-99.99; chain (KFONDO:KDATA) RecQuote; quota=%CHAR(VQUOTA); /end-free c
Il punto di partenza
Per la creazione del servizio partiamo dal sorgente wsdl che rappresenta la nostra logica e, al fine di ottenere un maggior livello di astrazione e riutilizzo, i tipi di dati (schema) utlizzati dal servizio, non sono direttamente inseriti all’interno del sorgente wsdl, ma in un file .xsd indipendente.Di seguito sono riportati lo schema e il wsdl utilizzati nell’ esempio.
Quota.xsd
xmlns:ts=”http://www.quota.schema.com”
targetNamespace=”http://www.quota.schema.com”>
Quota.wsdl
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
xmlns:wsdl=”http://schemas.xmlsoap.org/wsdl/”
xmlns:soap=”http://schemas.xmlsoap.org/wsdl/soap/”
xmlns:ns=”http://www.testquote.iSeries.com” name=”QuotaFondo”
targetNamespace=”http://www.quota.wsdl.com”>
xmlns:quota=”http://www.quota.schema.com”
targetNamespace=”http://www.quota.wsdl.com”
xmlns:tns=”http://www.quota.wsdl.com”>
namespace=”http://www.quota.schema.com”/>
type=”quota:QuotaRequestType”/>
type=”quota:QuotaResponseType”/>
transport=”http://schemas.xmlsoap.org/soap/http”/>
=”http://localhost:9080/QuotaServicePrj/services/ValoreQuota”/>
Il workspace e i progetti
Come prima cosa lanciamo lo strumento ASTK e creiamo il workspace sul quale vogliamo lavorare, per esempio D:workspaceQuota. Creiamo un progetto semplice che chiameremo SharedLibray (fig. 1) nel quale copieremo tutti gli oggetti JAR di comune utilità, nel nostro caso in particolare tutti i pacchetti presenti nella cartella lib di JTOpen.
Creiamo ora il vero e proprio progetto web dinamico che ospita il servizio e il progetto enterprise al quale sarà associato (Fig. 2)
Lasciamo tutti i parametri di default e dopo la creazione andiamo nelle proprietà del progetto web, selezioniamo: percorso di generazione e aggiungiamo al progetto tutti i jar presenti nel progetto SharedLibrary (fig. 3).
La creazione del servizio
Il prossimo passo è quello di copiare nella cartella src del progetto QuotaServicePrj gli archivi Quota.wsdl e Quota.xsd. Passiamo ora a generare il servizio vero e proprio partendo dal nostro wsdl.
Tasto destro su Quota.wsdl > Servizi Web > Genera struttura bean Java .Confermiamo tutti i parametri e premiamo Fine (fig. 4) assicurandoci, prima di effettuare questa fase, che l’istanza del server WebSphere sia attiva.
Al termine di questo passo avremo a disposizione la classe wrapper “vuota” (riportata di seguito) alla quale dovremo fornire successivamente l’implementazione.
package com.wsdl.quota.www;public class QuotaBindingImpl implements com.wsdl.quota.www.QuotaPort{ public com.wsdl.quota.www.QuotaOutput getQuota( com.wsdl.quota.www.QuotaInput parametri) throws java.rmi.RemoteException { return null; } }
PCML
Program Call Markup Language (PCML) come dice la definizione stessa è un linguaggio di marcatura che facilita il richiamo di applicazioni scritte per architetture AS400/iSeries. PCML mette a disposizione una serie di tag che permettono di modellare le chiamate ai programmi su AS400/iSeries all’interno di programmi Java. Il valore aggiunto di PCML risiede nel fatto che a partire dai tag vengono generati tutti gli oggetti necessari per richiamare il programma AS400/iSeries riducendo notevolmente la quantità di codice necessaria. Il codice PCML può essere creato direttamente da noi (come in questo caso) in funzione dei parametri richiesti dalla procedura, oppure generato direttamente durante la fase di compilazione del sorgente RPG.
Quota.pcml ="/QSYS.LIB/MYLIB.LIB/MYPGM.PGM" threadsafe="false">
Il tag program name rappresenta il nome “logico” del programma mentre path identifica il programma target che nello specifico è ubicato nella libreria MYLIB (nella libreria di sistema QSYS) e ha come nome MYPGM. L’attributo threadsafe viene utilizzato quando l’applicazione Java e la procedura risiedono sullo stesso server; in questo caso entrambi vengono eseguiti nello stesso job e nello stesso thread. Il file Quota.pcml deve essere copiato nella cartella src del progetto QuotaServicePrj in questo modo viene automaticamente inserito nella cartella classes dell’applicazione Web.
Forniamo l’implementazione
Di seguito è riportata una possibile implementazione del servizio. Le credenziali dell’utente per l’accesso alla macchina possono essere, come in questo caso, inserite direttamente nel codice, oppure più elegantemente collegate a dei nomi logici all’interno del name space dell’application server.
package com.wsdl.quota.www; import com.schema.quota.www.*; import com.ibm.as400.access.AS400; import com.ibm.as400.data.ProgramCallDocument; public class QuotaBindingImpl implements QuotaPort { public QuotaOutput getQuota(QuotaInput parametri) throws java.rmi.RemoteException { AS400 conn = new AS400("serverIP", "utente", "password"); QuotaOutput qout = new QuotaOutput(); QuotaResponseType qres = new QuotaResponseType(); try { ProgramCallDocument pcml = new ProgramCallDocument(conn, "Quota"); pcml.setValue("QuotaRPG.fondo", parametri.getQuotaInput() .getFondo()); pcml.setValue("QuotaRPG.valuta", parametri.getQuotaInput() .getData()); boolean pgm = pcml.callProgram("QuotaRPG"); if (pgm != true) { System.out.println("Errore MYLIB/MYPGM"); } else { String risultato = (String) pcml.getValue("QuotaRPG.valore"); qres.setValore(risultato); qout.setQuotaOutput(qres); } } catch (Exception ex) { System.out.println("Errore MYLIB/MYPGM"); ex.printStackTrace(); } finally { if (conn != null) { conn.disconnectService(AS400.COMMAND); } } return qout; } }
Per prima cosa viene creata una connessione (rilasciata poi nel finally) verso la macchina AS400 specificando indirizzo IP, utente e password; successivamente viene istanziato un oggetto di tipo ProgramCallDocument specificando nel suo costruttore la connessione appena creata e il nome del sorgente PCML: Quota (.pcml è assunto come default).
L’oggetto ProgramCallDocument coopera con il server DCP (Distribuited Programm Call) per lo scambio dei paramtri richiesti dall’applicazione; il metodo setValue imposta i parametri richiesti dalla procedura RPG precedentemente definiti nel sorgente pcml. L’esecuzione vera e propria della procedura RPG avviene grazie al metodo callProgram al quale viene passato il nome del programma specificato nel tag program name. Se l’invocazione ha avuto esito positivo, il valore di ritorno viene ottenuo invocando il metodo getValue. Le classi com.ibm.as400.access.AS400 e com.ibm.as400.data.ProgramCallDocument si trovano nel package jt400.jar.
Realizziamo il client per il test
Per testare il nostro lavoro ci appoggiamo sempre ai tool messi a disposizione da ASTK. Tra i vari tipi di Test Client è possibile generarne uno stile web (fig. 5 ). Per prima cosa dovremo specificare l’endpoint al quale il servizio risponde e successivamente fornire i parametri richiesti, e se tutto funziona correttamente, l’invocazione del programma RPG ritornerà il valore unitario del nostro fondo di investimento.
Conclusioni
Abbiamo visto che grazie alle funzionalità messe a disposizione del tool ASTK e all’utilizzo delle classi fornite dal progetto JTOpen è possibile “interfacciare” Java con applicazioni scritte per sistemi AS400/iSeries. Questo livello di “integrazione” oltre a preservare le applicazioni “legacy” esistenti permette a queste ultime di essere visibili e riutilizzabili in contesti applicativi più ampi. È importante sottolineare che è possibile, anzi consigliabile, pubblicare il servizio non direttamente sull’application Server ma sul System Integration Bus (SIB) interno a WebSphere, che realizza un efficiente strato ESB.
Riferimenti
[1] S. Rossini – M. Piraccini, “Architetture di integrazione”, MokaByte
[2] JTOpen
http://jt400.sourceforge.net
[3] AS/400 XML
http://www.redbooks.ibm.com/abstracts/sg245959.html
[4] Web Services for WAS 6.1
http://www.redbooks.ibm.com/abstracts/sg247257.html