Jon Paris
Jon.Paris @ Partner400.com www.Partner400.com www.SystemiDeveloper.com
"Instant" Web Services and Stored Procedures
NotesJon Paris is co-founder of Partner400, a firm specializing in customized education and mentoring services for IBM i * developers.
Jon's career in IT spans 40+ years including a 12 year period with IBM's Toronto Laboratory.
Together with his partner Susan Gantner, Jon devotes his time to educating developers on techniques and technologies to extend and modernize their applications and development environments. Together Jon and Susan author regular technical articles for the IBM publication, IBM Systems Magazine, IBM i edition, and the companion electronic newsletter, IBM i EXTRA. You may view articles in current and past issues and/or subscribe to the free newsletter at: www.IBMSystemsMag.com.
Jon and Susan also write a weekly blog on Things "i" - and indeed anything else that takes their fancy. You can find the blog here: ibmsystemsmag.blogs.com/idevelop/
Feel free to contact the author at: Jon.Paris @ Partner400.com
* IBM i - aka AS/400, System i, iSeries, i5, etc.
How? • XMLSERVICE - the latest IBM toolkit
What is it ? • And why did we need a new toolkit ?
What is different about it ? • It is Open Source and written in RPG!
How is it used ? • From other languages and platforms
Agenda
XMLSERVICE - What Is It ?Originally created as part of the Zend/IBM partnership • Now the core of Zend's PHP Toolkit for IBM i • And the new toolkits for:
✦ Node.js, Python, Ruby, and .Net ✦ plus many more to come
Allows usage of any program or utility on your IBM i • Programs, Service Programs, CL commands, PASE utilities, ...
From anywhere • Another IBM i, Windows, Unix, Linux, ...
Once set up nothing else required • New programs can be accessed without any additional work
Two forms of access supported • Web Service • Stored Procedure
Development site hosted by the Young i Professionals • youngiprofessionals.com
Why Did We Need a New Toolkit ?Limitations in existing tooling • Java toolbox does not support return values
✦ Except for four byte integers - Note that this limitation can be avoided in V7 by recompiling your RPG
subprocedures to use the new RTNPARM keyword • Requires use of Java by requesting platform
✦ Alternatively the other platform needs a Java bridge - In all other cases you are limited to ODBC capability
• Java programming skills required to enhance toolbox • Slow to deploy new functionality
✦ If Java programmers didn't need it there was no incentive to add it • New functionality means changes in PCML generation
✦ So you have to wait for the compiler team to implement it • The result?
✦ It took years to get new data types added to the interface
Why Did We Need a New Toolkit ?We need an easy way to show "IBM i can do it!" • i.e. a method to quickly prototype reuse of existing functionality • Otherwise manual effort is required to deploy new functionality
✦ Have to set up a new web service or stored procedure or .. Limited support for persistence • Problematic if you want to deploy an existing 5250-style
application as a web service or browser application Proprietary Technology • Java toolkit originally developed by IBM
✦ Subsequently released as Open Source • Previous PHP toolkit was actually produced by Aura
✦ Known by Aura as EasyCom
What is Different About the New Toolkit ?Open Source under BSD License • Completely free to use 100% RPG IV • Any RPG programmer can modify All communications via XML documents • Easier to debug • Automatic conversion between ASCII and EBCDIC Usable in single and two tier environments • All code on single IBM i • Or any other system to IBM i Supports persistent connections • Called RPG programs can retain state information
✦ i.e. Just as they normally do in a 5250 job • Facilitates repurposing of existing 5250 applications as web
services or browser jobs
What is Different About the New Toolkit ?Supports complex parameter types • Arrays, DS, DS Arrays, Compound DS, ...
Program calls and commands can be run in sequence • Ensures that results of one operation are available to the next
Directly supports return values • As noted earlier, RPG's V7 RTNPARM keyword also allows you
to avoid this problem Can be invoked from any Client-side language • As long as it can invoke a web service • Or use an SQL connection
Security • Requires use of valid user name and password
✦ No matter what protocol is used • Facilitates access control to IBM i resources
Toolkit ArchitectureCross Platform Language Agnostic • Accessible from any language • Toolkits available for IBM i supported languages
How Is It Used ? - From PHP New Zend Toolkit uses XMLSERVICE under the covers • Supports all previous functionality and more • Completely new set of APIs
✦ Plus "wrappers" to allow existing code to use the new APIs • Delivered as part of the Zend Server download
✦ Or obtain from Young i Professionals site if using from another platform
• yips.idevcloud.com/wiki/index.php/XMLService/XMLSERVICE
Allow PHP access from other platforms • e.g. Linux, Windows, Mac, etc. • The Zend components are also Open Source
All of the new APIs use an OO approach • Still very easy to use for the non-OO programmer
XMLSERVICE: Stored Procedure InterfaceSupplied stored procedures are the preferred access method • Can be accessed via ODBC, JDBC, DB2Connect, etc.
Can be used to access any program • Eliminates need to create one stored procedure per program
Accepts four parameters • IPC Key
✦ A path to an IFS folder associated with a specific XMLSERVICE job - This is part of the persistence mechanism
• CTL ✦ Parameters to control the service job's behavior
- e.g Debug mode, shut down job, etc. • CLOB In and CLOB out
✦ The Input and Output XML documents
XMLSERVICE: REST Web Service InterfaceTakes Seven Parameters
✦ Note that three are the same as for the Stored Procedure interface db2 • Name of database to access (*Local or Database name)
uid • User Id
pwd • Password
ipc and ctl • Same as for the IPC and CTL Stored Procedure parameters
xmlin • XML Input document
xmlout • Maximum expected size of returned XML output document
XML Document Elements<cmd> … </cmd> • Executes the command line command specified between the <cmd> tags
<sh> … </sh> • PASE equivalent of the <cmd> tag.
<pgm> … </pgm> • Identifies program or subprocedure to be run
✦ Attributes name= lib= and func= identify program name, library, and subprocedure name ✦ Parameters and return values for the program are defined within the <parm> element
<parm> … </parm> • Identifies a parameter. More details on next chart
<ds> … </ds> • Indicates that the parameter is a data structure. More details on next chart
<data> … </data> • Defines the parameter and populates it.
<return> … </return> • Identifies the return value on a subprocedure.
✦ Definition of the return value is via <data> and <ds> tags just like parameters
XML Document Element Attributes<parm> attributes • io=... Parameter type "in" "out" or “both” • by=... Parameter passing method
✦ “val” (value) or “ref” (reference) <ds> attributes • dim=... Maximum number of DS array elements • dou=... Number of array elements actually populated.
<data> attributes • var=... Names the variable • type=... Data type and size
✦ e.g. 12a, 15p5, 9s2, etc. • varying=... *on indicates a varying length field.
<?xml version="1.0"?> <mult> <cmd comment='addlible'>+++ success ADDLIBLE LIB(JONSLIB)</cmd> <pgm name='MYPGM' lib='JONSLIB' func='MYPGM'> <parm .....
Other Features of the XML DocumentsA single XML document can contain multiple requests • They will be performed in sequence • Makes it simple to perform tasks like setting the library list
Success or failure is indicated in the returned document • See example in document below
Tags and attributes not used by XMLSERVICE are allowed • They are simply passed through and included in the XML output • You can add extra markup to assist in parsing returned XML • Or comments that will aid in debugging
< ?xml version='1.0'? > < pgm name='XMLSRVTST1' lib='XMLSERVICE' > < parm > < data type='15p5' >5678901234.54321< /data > < /parm > < parm > < data type='30A' >Original value< /data > < /parm > < /pgm >
Simple Example of the Web Service InterfaceA simple program that takes two parameters • A 15 digit packed numeric and a 30 character • The second parameter will be modified by the called program
The User of your web service must send the XML shown below
This is the XML representation of
the prototype shown above
// Proto for XMLSRVTST1 d XMLSrvTst1 pr ExtPgm(‘XMLSRVTST1’) d input 15p 5 d output 30a
// Relevant portion of the XML document returned < ?xml version='1.0'? > < pgm name='XMLSRVTST1' lib='XMLSERVICE' > < parm > < data >5678901234.54321< /data > < /parm > < parm > < data >Input was 5678901234.54321< /data > < /parm > < /pgm >
XML Returned by the Web ServiceThe document returned is almost identical to the one we sent • But the parameter details (length and type) are omitted • And the contents of the second parm have changed
✦ This is highlighted below More on the XML in a moment
// Proto for XMLSRVTST1 d XMLSrvTst1 pr ExtPgm(‘XMLSRVTST1’) d input 15p 5 d output 30a
Original field definitions are not returned in the response document. Only the field values
D LookupTest Pr LikeDS(rec_T) Dim(10) D searchFor 10a D max 10i 0 D count 10i 0
<pgm name='MYSRVPGM' func='LOOKUPTEST'> <parm comment='search for this name'> <data var='searchFor' type='10A'>Paris</data> </parm> <parm comment='max allowed return'> <data var='max' type='10i0'>5</data> </parm> <parm comment='count of records returned'> <data var='count' type='10i0' enddo='count'>0</data> </parm>
<return> <ds var='rec_t' dim='10' dou='count'> <data var='name' type='30A'>na</data> <data var='job' type='40A'>na</data> <data var='pay' type='9p2'>0.0</data> </ds> </return> </pgm>
More Complex XML Call DocumentElements and attributes not required by XMLSERVICE are echoed • Useful in debugging returned data
✦ Note the use of the field names
Document Returned From Procedure Call
<pgm name='MYSRVPGM' func='LOOKUPTEST'> <parm comment='search for this name'> <data var='searchFor'>Paris</data> </parm> <parm comment='max allowed return'> <data var='max'>5</data> </parm> <parm comment='count of records returned'> <data var='count'>3</data> </parm> <return> <ds var='rec_t'> <data var='name'>Jon Paris</data> <data var='job'>Chief Cook and Bottle Washer</data> <data var='pay'>13.42</data> </ds> <ds var='rec_t'> <data var='name'>Susan Gantner-Paris</data> <data var='job'>Manager</data> <data var='pay'>26.84</data> </ds> ... </return> </pgm>
Original field definitions are not returned in the response document. Only the field values
The New XMLService Web Demo Page Nothing but HTML! • Honestly
Not pretty - but pretty amazing nonetheless • Examples of SQL, calling programs, issuing commands, etc.
65.183.160.36/Samples/Toolkit_HTML/index.html • Use browser's View Source to see the underlying HTML/XML
<!-- XMLSERVICE call a *SRVPGM (time *USA) --> <form name="input" action="/cgi-bin/xmlcgi.pgm" method="post"> <input type="hidden" name="db2" value="*LOCAL"> <input type="hidden" name="uid" value="*NONE"> <input type="hidden" name="pwd" value="*NONE"> <input type="hidden" name="ipc" value="/tmp/rangerhtmlonly"> <input type="hidden" name="ctl" value="*sbmjob"> <input type="hidden" name="xmlin" value= "<?xml version='1.0'?> <?xml-stylesheet type='text/xsl' href='/wiki/uploads/XMLService/DemoXslt.xsl'?> <script> <pgm name='ZZSRV' lib='XMLSERVICE' func='ZZTIMEUSA'> <parm io='both'> <data type='8A'>09:45 AM</data> </parm> <return> <data type='8A'>nada</data> </return> </pgm> </script>">
<input type="hidden" name="xmlout" value="5000"> <input type="submit" value="call *SRVPGM (ZZTIMEUSA)" /> </form>
Example of HTML UsedThis is the HTML code used to call the subprocedure ZZTIMEUSA • Note how the XML data is defined
Note that the XML packet is specified as the value
for the xmlin variable
It ends here
More info and examples of PHP usage follow but I will not have time to go into them in detail.
Contact me in the break or by email after the event if you have questions.
PHP Methods and Functions in ToolkitService
The main class that manages all DB2 settings and communication • Methods to Set Database Connections and XMLService Options
CLCommand • Run CL commands either in interactive or batch mode
PGMCall method • Calls programs (*PGM) or service programs (*SRVPGM)
AddParameterxxxx methods • Define the program parameters. • Methods available for all the usual suspects
SetParameterValue • Sets new parameter values
disconnect interface • Terminates an XML service job in the ZENDSVR subsystem • Don't use this with persistent jobs unless and until you want to
To Save You a Lot of Work ...A tool to convert D specs to PHP code • You can find it at: yips.idevcloud.com/Samples/DSpecTool/ • Hopefully it will support free-form declarations soon
PHP Usage - Issue Interactive CL Command
<?php
include_once 'authorization.php'; include_once '../API/ToolkitService.php';
$obj = ToolkitService::getInstance($db, $user, $pass);
$parms = array('InternalKey'=>"/tmp/$user",'debug'=>true,'plug' => "iPLUG32K");
$obj->setToolkitServiceParams($parms);
$cmd = "addlible ZENDSVR";
$obj->CLCommand($cmd);
$Rows = $obj->CLInteractiveCommand("DSPLIBL");
if($Rows) var_dump($Rows); else echo $obj->getLastError();
$obj->disconnect();
?>
Copy in toolkit script
Copy User Id, and Password plus default library etc.
Controls the maximum size of message that
can be handled
Initial CL Command is executed followed by
the interactive command below
Interactive command returned a result set - the 5250 display data
PHP Usage - Call RPG Program
<?php
include_once 'authorization.php'; include_once '../API/ToolkitService.php';
$extension='ibm_db2';
$ToolkitServiceObj = ToolkitService::getInstance($db, $user, $pass, $extension); $ToolkitServiceObj->setToolkitServiceParams(array('InternalKey'=>"/tmp/$user"));
$code = $_POST ['code']; // Get value of Code field from input $desc = ' '; // Blank the output parameter
$param[] = $ToolkitServiceObj->AddParameterChar('both', 10,'CODE', 'CODE', $code); $param[] = $ToolkitServiceObj->AddParameterChar('both', 10,'DESC', 'DESC', $desc);
$result = $ToolkitServiceObj->PgmCall("TESTPGM", "ZENDSVR", $param, null, null);
if($result) var_dump($result['io_param']); else echo "Execution failed.";
$ToolkitServiceObj->disconnect();
?>
RPG program requires two parameters each 10
characters long. The previous lines placed
them in the array
Set up the parameters
PHP Usage - Call Service Program Procedure
<?php ... $SysValueName = "QCCSID";
$param[] = $ToolkitServiceObj->AddParameterChar('both', 1,'ErrorCode','errcode', $Err); $param[] = $ToolkitServiceObj->AddParameterChar('both', 10,'SysValName','sysvalname', $SysValueName); $param[] = $ToolkitServiceObj->AddParameterChar('both', 1024,'SysValue','sysvalue', $SysValue);
$OutputParams = $ToolkitServiceObj->PgmCall('ZSXMLSRV', "ZENDSVR", $param, NULL, array('func'=>'RTVSYSVAL') );
if( isset($OutputParams['io_param']['sysvalname'])) echo " System value ".$SysValueName." = ".$OutputParams['io_param']['sysvalue']; else echo "System value $SysValueName was not retrieved.";
// Change requested value and execute call again ProgramParameter::UpdateParameterValues( $param, array("sysvalname"=>"QLANGID"));
$OutputParams = $ToolkitServiceObj->PgmCall('ZSXMLSRV', "ZENDSVR", $param, NULL, array('func'=>'RTVSYSVAL') ); ... ?>
Function name
Change parameter value
iToolkitClass Methods and Functions - Part 1
Data Queue • CreateDataQ() • DeleteDQ() • ReceieveDataQueue() • SendDataQueue() • SetDataQName() • ClearDQ() User Space • CreateUserSpace() • RetrieveUserSpaceAttr() • RetrieveUserSpaceSize() • DeleteUserSpace() • WriteUserSpace() • ReadUserSpace()
iToolkitClass Methods and Functions - Part 2
Spooled Files • GetSPLList() • GetSPLF() System Values • SystemValuesList() • GetSystemValue() Job Log • JobList() • JobLog() • GetJobInfo Object List • getObjectList()
If you think of any questions after the session please email me:
Jon.Paris @ Partner400.com
Questions ?