SVFileService Example
This example program performs the following steps:
1. Performs a series of calls necessary to load the SVFileService
2. Writes a CSV file containing order line data to file SVFILE.CSV in the JSM instance folder – in this simple example, the data comes from compile-time array data coded in the RPG program, but it could equally well have come from a database or have been received in various formats through another LANSA Integrator service call
3. Unloads the service and closes the connection to the JSM server.
Refer to the comments and code in the example for more information.
There are four steps required to make this application work:
1. Create the structure XML
The call to the WRITE command of the SVFileService passes a multiple occurrence data structure containing the order line items that will be written to the CSV file. For this to work, the LANSA Integrator service needs to know the characteristics of this structure. This is accomplished by supplying an XML file that describes the structure.
For this example, the required XML is supplied below. To install this XML you need to perform the following steps:
a. Locate the structure folder in the JSM instance folder for your JSM server.
b. Create a file called SVOrderLine.xml.
c. Edit the file with a text editor and paste into it the xml supplied below.
Note that the field names used in the structure XML do not need to match the variable names used in the RPG program (although they do match in this example). It is their order, types and length that are important – not their names.
<?xml version="1.0" encoding="UTF-8"?>
<rdml:structure xmlns:rdml="http://www.lansa.com/2000/XML/Function">
<rdml:field name="LINENUM" type="S" length="7" />
<rdml:field name="PARTNUM" type="A" length="7" />
<rdml:field name="PARTDSC" type="A" length="30" />
<rdml:field name="PARTAMT" type="S" length="9" decimal="2" />
<rdml:field name="PARTQTY" type="S" length="7" />
</rdml:structure>
2. Register the structure XML with the JSM Server
The example program refers to the structure XML supplied above with the symbolic name SV.SVOrderLine by specifying that name in the SERVICE_STRUCTURE keyword of the WRITE command.
We need to give the JSM Server a link between that symbolic name and the actual name and location of the structure XML file created in step 1. To do this you need to perform the following steps:
a. Locate the system folder in the JSM instance folder for your JSM server.
b. Edit the file structure.properties with a text editor and paste into it the entry supplied below (make sure the new entry is on a line by itself).
c. Save your changes.
d. Restart or refresh the JSM Server instance (refer to Java Service Manager Refresh).
structure.SV.SVOrderLine=structure/SVOrderLine.xml
3. Define the header for the resulting CSV
The contents of the SVFILE.CSV file that is created by this sample should look similar to this:
LINENUM,PARTNUM,PARTDSC,PARTAMT,PARTQTY
1,123,Gasket Paper,9.95,10
2,456,Gasket polymer glue,13.27,5
You will note that the first record contains column names (or headings). Many programs that process CSV data will or can recognize and make use of these column names.
The SVFileService creates these column headings optionally. If you wish to include them, then you need to specify the SVHEAD parameter of the WRITE command.
This example, specifies the symbolic name ORDER for the SVHEAD parameter. This symbolic name identifies a set of column headings that are specified in the service properties file for the SVFileService. Therefore you need to perform the following steps to add the definition to the service properties file (if it is not already there):
a. Locate the properties folder in the JSM instance folder for your JSM server
b. Edit the file SVFileService.properties with a text editor and paste into it the entry supplied below, if it is not already there (make sure that the new entry is on a line by itself)
c. Save your changes
d. Restart or refresh the JSM Server instance (refer to Java Service Manager Refresh).
Note that the column headings used do not need to match the variable names used in the RPG program or in the structure XML (although they do match in this example).
sv.head.order=LINENUM,PARTNUM,PARTDSC,PARTAMT,PARTQTY
4. Create and run the ILE RPG example program
Copy and paste the source provided below into a source file member.
To create the program, you need to use the CRTRPGMOD and CRTPGM commands. Make sure that you use the parameter values specified in the source member.
*************************************************
* SVFILE: example in RPG ILE of using the LANSA Integrator
* SVFileService to write a comma-separated file
*
* Note: This is an example program containing only
* rudimentary exception handling
*
* To create this program you must execute the following commands,
* supplying the indicated parameter values and any others that are
* necessary in your installation:
*
* CRTRPGMOD MODULE(<modlib>/SVFILE)
* SRCFILE(<srclib>/<srcfil>)
*
* CRTPGM PGM(<pgmlib>/SVFILE)
* MODULE(<modlib>/SVFILE)
* BNDSRVPGM(<jsmpgmlib>/DCXS882X)
* ACTGRP(*CALLER)
*************************************************
* Path of the CSV file created by this program
* - because no folder path is specified, the file will be created
* in the JSM instance folder by default
d svfilepath c const('SVFILE.CSV')
* Declare variables for the JSM calls
d jsmsrv s 50a inz(*blanks)
d jsmsts s 20a inz(*blanks)
d jsmmsg s 255a inz(*blanks)
d jsmcmd s 255a inz(*blanks)
d bytelength s 10i 0 inz(*zero)
* Declare structure to send order line data to be written to the
* comma-separated file:
* - in this simple example, the data comes from the compile-time
* array data, but it could equally well have come from a database
* or received through another LANSA Integrator service call
* NB: This MUST match the structure xml provided to the JSM Server!
d svlist ds occurs(svocur) based(svlistptr)
d linenum 7s 0
d partnum 7a
d partdsc 30a
d partamt 9s 2
d partqty 7s 0
d svocur c const(2)
d svsize c const(%size(svlist))
* Declare the compile-time array that provides the data for
* this simple example
d svdata s 60a dim(svocur) perrcd(1) ctdata
* Completion messages
d CompMsg01 c 'JSMOPEN call completed.'
d CompMsg02 c ' SERVICE_LOAD call completed.'
d CompMsg10 c ' WRITE call completed.'
d CompMsg98 c ' SERVICE_UNLOAD call completed.'
d CompMsg99 c 'JSMCLOSE call completed.'
* Procedure prototypes
d CheckResult pr
d crjsts const like(jsmsts)
d crjmsg const like(jsmmsg)
d SendMessage pr
d smText 512a VALUE
d smType 10a VALUE
* Prototypes for the JSM calls
/COPY QRPGLESRC,JSM_PROC.H
* Open a connection to the default JSM server
* - because the server parameter is blank, details of the default
* JSM server are obtained from the data area JSMCLTDTA on IBM i
* or from the file jsmcltdta.txt on other supported platforms)
c callp p_jsmopen(jsmsrv:jsmsts:jsmmsg)
c callp CheckResult(jsmsts:jsmmsg)
c callp SendMessage(CompMsg01:'*COMP')
* Load the SVFileService
* - this example explicitly turns tracing on, overriding the
* settings in the manager.properties file
c eval jsmcmd = 'SERVICE_LOAD'
c + ' SERVICE(SVFILESERVICE) TRACE(*YES)'
c callp p_jsmcmd(jsmcmd:jsmsts:jsmmsg)
c callp CheckResult(jsmsts:jsmmsg)
c callp SendMessage(CompMsg02:'*COMP')
* Populate the list to be written to the CSV file
* - in this simple example, the data comes from the compile-time
* array data, but it could equally well have come from a database
* or received through another LANSA Integrator service call
c eval svlistptr = %addr(svdata)
* Write a comma-separated list of items from the compile-time array
* - the SVHEAD parameter identifies headings (defined in the SVFILESERVICE
* service properties file) that will be written to the CSV file
* - this passes the multiple occurrence data structure
* (svlist) containing the items
* - the structure is described to the SVFileService by the
* structure XML identified by the SERVICE_STRUCTURE keyword - there
* must be a matching entry in the structure.properties file and a
* corresponding structure XML file, usually in the <instance>\Structure
* folder
* NOTE: this call uses the JSMCMDX api in order to be able to send
* variable data (in this case the structure/list)
c eval jsmcmd = 'WRITE'
c + ' FILE(' + %trim(svfilepath) + ')'
c + ' SVHEAD(ORDER)'
c + ' SERVICE_STRUCTURE(SV.SVOrderLine)'
c + ' COUNT(' + %char(svocur) + ')'
c + ' OCCURS(' + %char(svocur) + ')'
c + ' SIZE(' + %char(svsize) + ')'
c eval bytelength = svocur * svsize
c callp p_jsmcmdx(jsmcmd:svlist:bytelength:
c jsmsts:jsmmsg)
c callp CheckResult(jsmsts:jsmmsg)
c callp SendMessage(CompMsg10:'*COMP')
* Unload the SVFileService
c eval jsmcmd = 'SERVICE_UNLOAD'
c callp p_jsmcmd(jsmcmd:jsmsts:jsmmsg)
c callp CheckResult(jsmsts:jsmmsg)
c callp SendMessage(CompMsg98:'*COMP')
* Close the connection to the JSM server and finish
c callp p_jsmclose(jsmsts:jsmmsg)
c callp CheckResult(jsmsts:jsmmsg)
c callp SendMessage(CompMsg99:'*COMP')
c eval *inlr = *on
c return
*************************************************
* Procedure to check the result of a Java Service Manager call
*************************************************
p CheckResult b
d CheckResult pi
d crjsts const like(jsmsts)
d crjmsg const like(jsmmsg)
d crText s 512a
d crMsg1 c const('JSM Status : ')
d crMsg2 c const('JSM Message: ')
d crMsg3 c const('JSM Service error has +
d occurred')
c if crjsts <> 'OK'
c eval crText = crMsg1 + crjsts
c callp SendMessage(crText:'*DIAG')
c eval crText = crMsg2 + crjmsg
c callp SendMessage(crText:'*DIAG')
c callp SendMessage(crMsg3:'*ESCAPE')
c endif
p CheckResult e
*************************************************
* Procedure to send a program message
*************************************************
p SendMessage b
d SendMessage pi
d smText 512a VALUE
d smMsgT 10a VALUE
d smMsgI s 7a inz('CPF9897')
d smMsgF s 20a inz('QCPFMSG *LIBL ')
d smDtaL s 10i 0 inz(%size(smText))
d smStkE s 10a inz('*')
d smStkC s 10i 0 inz(1)
d smMsgK s 4a
d smErrC s 10i 0 inz(0)
c if smMsgT = '*ESCAPE'
c eval smMsgI = 'CPF9898'
c endif
c call 'QMHSNDPM'
c parm smMsgI
c parm smMsgF
c parm smText
c parm smDtaL
c parm smMsgT
c parm smStkE
c parm smStkC
c parm smMsgK
c parm smErrC
p e
**CTDATA svdata
0000001123 Gasket Paper 0000009950000010
0000002456 Gasket polymer glue 0000013270000005