Program

(click to open)

Quick Page Table of Contents

Scanning…

Ruby Toolkit Don Calling an IBMi program …

XMLSERVICERubyDonWork

THIS PAGE IS COMPLETELY OUT OF DATE (WRONG)

do not use

The easiest way to test XMLService’s program call is to use the Rails console. Otherwise you will need to create a controller to execute your IBMi program call, build a view to display the output, and then modify /config/routes with the URL to the controller action. Note that you can copy and paste lines of Ruby code into your QP2Term session. This document places the program call code in a Rails helper. That helper can later be used from a controller but, initially, to get comfortable with XMLService, we will invoke the helper method from the Rails console. We will be calling a program called ZZCALL that exists in the XMLSERVICE library that was installed with PowerRuby.

Be sure to set the Ruby and Rails version that was used when you created your Rails application before launching Rails console.

Place the following in your Rails application’s app/helpers directory with the name of zzcall_helper.rb

require 'xmlservice'

module ZzcallHelper
  def self.callpgm()
    ActiveXMLService::Base.establish_connection connection: 'ActiveRecord'
    in_inds1 = {'dschara'=>'x','dscharb'=>'y','dsdec1'=>66.6666,'dsdec2'=>77777.77}
    zzcall = XMLService::I_PGM.new("ZZCALL", 'XMLSERVICE') <<
       XMLService::I_a.new('inchara',1,'a') <<
       XMLService::I_a.new('incharb',1,'b') <<
       XMLService::I_p.new('indec1',7,4,11.1111) <<
       XMLService::I_p.new('indec2',12,2,222.22) <<
       XMLService::I_DS.new("inds1",1,
       [
        XMLService::I_a.new('dschara',1,in_inds1['dschara']),
        XMLService::I_a.new('dscharb',1,in_inds1['dscharb']),
        XMLService::I_p.new('dsdec1',7,4,in_inds1['dsdec1']),
        XMLService::I_p.new('dsdec2',12,2,in_inds1['dsdec2'])
       ])
     zzcall.xmlservice
     puts "zzcall.xml_PARM3.xml_indec2: "+zzcall.xml_PARM3.xml_indec2.to_s
  end
end

Then launch the Rails console, include the helper, and then invoke the program call:

===> cd /your/rails/apps/root/dir
===> rails console
===> include ZzcallHelper
===> ZzCallHelper.callpgm

Your shell session will then show:

zzcall.xml_PARM3.xml_indec2: 1234567890.12

The following displays the parameters in the ZZCALL RPG SOURCE

Appending Parameters to the Program

For those not completely comfortable with Ruby, the use of the double less than symbol (‘<<’, a.k.a. the left shift operator) used in the above program call may be confusing. The Ruby language uses the left shift operator in low-level numbers to shift bits to the left but Ruby also uses the left shift operator to append elements to arrays. The cool thing about the Ruby language is that you can write your own methods to be invoked when the left shift operator is used on your object (as well as all the other available operators in the Ruby language). XMLService uses the left shift operator to append parameters to the I_PGM program object. Furthermore, XMLService allows you to chain the construction of the parameters, e.g.:

pgm_with_2_params = XMLService::I_PGM.new('PGM2PARMS', 'BOGUS') << XMLService::I_a.new('parm_1',1,'a') << XMLService::I_a.new('param_2',1,'b')

Data types

The parameters in ZZCALL RPG SOURCE may be more complex than what a typical IBMi shop might use as it contains a nested data structure. But it is good to know that XMLService is ready to handle your most complex RPG program parameters. The ZZCALL sample program used, as well as the data structure, single character and decimal params.

The following are all the types available in XMLService and a description of the parameters used when constructing each type:

Character Parameters

Create a character parameter by invoking new with the parameter name, total length, and initial value, e.g.: XMLService::I_String.new('last_name', 15, 'Denoncourt')

  • I_a, I_String, (synonym for I_a)
  • I_a_varying_2, I_VarChar2, (synonym for I_a_varying_2)
  • I_a_varying_4, I_VarChar4, (synonym for I_a_varying_4)

Numeric Parameters

Create a numeric parameter by invoking new with the parameter name, total length, decimals, and initial value, e.g.: XMLService::I_Int32.new('thirty_two_bit', 20131112)

  • I_3i0, I_Int8 (synonym for I_3i0)
  • I_5i0, I_Int16 (synonym for I_5i0)
  • I_10i0, I_Int32 (synonym for I_10i0)
  • I_20i0, I_Int64 (synonym for I_20i0)
  • I_3u0, I_Uint8 (synonym for I_3u0)
  • I_5u0, I_Uint16 (synonym for I_5u0)
  • I_10u0, I_Uint32 (synonym for I_10u0)
  • I_20u0, I_Uint64 (synonym for I_20u0)
  • I_4f, I_Float4 (synonym for I_4f), I_Real (synonym for I_4f)
  • I_8f, I_Float8 (synonym for i_8f), I_Double (synonym for I_8f)
  • I_b, I_Binary (synonym for I_b)

Fixed Point Numeric Parameters

Create a fixed point parameter by invoking new with the parameter name, total length, decimals, and initial value, e.g.: XMLService::I_PackedDecimal.new('book_cost', 9, 2, 12.98)

  • I_p, I_PackedDecimal (synonym for I_p)
  • I_z, I_ZonedDecimal (synonym for I_z )

Return parameters

Retrieving the value of parameters that may have been altered by the called program is easy — once you know how to qualify the parameter. In the above example the following line listed a modified parameter:

 
puts "zzcall.xml_PARM3.xml_indec2: "+zzcall.xml_PARM3.xml_indec2.to_s 

The qualifier strategy that XMLService uses is ‘xml_PARM’ followed by the zero-based index of the parameter, the dot, then ‘xml_’ followed by the name of the parameter. So zzcall.xml_PARM3.xml_indec2 references the forth parameter constructed with:

XMLService::I_p.new('indec2',12,2,222.22) 

If you would like to have an explicit list of all the values available, use the dump_inspect method. For example, if you add the following line to the end of zzcall_helper’s callpgm method above, you will get a detailed dump of available attributes:

puts zzcall.dump_inspect

And here’s the list of attributes that the dump_inspect method call provides:

PARMS
.@xml_output
.@xml_PARM0
..@xml_inchara
.@xml_PARM1
..@xml_incharb
.@xml_PARM2
..@xml_indec1
.@xml_PARM3
..@xml_indec2
.@xml_PARM4
..@xml_inds1[]
...@xml_dschara
...@xml_dscharb
...@xml_dsdec1
...@xml_dsdec2

Debugging

Many things can go wrong in your program call. Your Rails application is running in its own IBMi job in PASE and the program call runs in the QSYS library context in another job. So it is important to get detailed information when your call fails. XMLService has a dump method that lists verbose details about errors in your program call. For example, the following is program call to an non-existing program:

zzcall = XMLService::I_PGM.new("ZZMISS", 'AINTTHER') #, options)
zzcall.xmlservice
if zzcall.xmlservice_error
  puts zzcall.dump
end

Which produces the following listing:

=== Dump ===
Version
  version: XML Toolkit 1.8.3
Job
 jobipc:      /none
 jobipcskey:  FFFFFFFF
 jobname:     QSQSRVR
 jobuser:     QUSER
 jobnbr:      627987
 jobsts:      *ACTIVE
 curuser:     DB2
 ccsid:       37
 dftccsid:    37
 paseccsid:   819
 langid:      ENU
 cntryid:     US
 sbsname:     QSYSWRK
 sbslib:      QSYS
 curlib:      
 syslibl:     QSYS QSYS2 QHLPSYS QUSRSYS
 usrlibl:     QGPL QTEMP
XMLError
 1100016 : XML run pgm failed : <pgm name='ZZMISS' lib='AINTTHER' error='off'></pgm
 1000005 : PASE resolve failed : ZZMISS
 1100016 : XML run pgm failed : <pgm name='ZZMISS' lib='AINTTHER' error='off'></pgm
JoblogScan
 CPF1124 : 12/03/13  09:47:02.505309
         : Job 627987/QUSER/QSQSRVR started on 12/02/13 at 12:33:02
 CPF1301 : 12/03/13  09:47:02.505309
         : DB2 QWTCCCHJ main 129 ACGDTA for 627987/QUSER/QSQSRVR not journaled; reason 1.
 CPF1336 : 12/03/13  09:47:02.505309
         : DB2 Errors on CHGJOB command for job 627987/QUSER/QSQSRVR.
 CPF1301 : 12/03/13  09:47:02.505309
         : DB2 QSQSRVR QSQSRVR 8408 ACGDTA for 627987/QUSER/QSQSRVR not journaled; reason 1.
 *NONE : 12/03/13  09:47:02.505309
         : DB2 QSQSRVR QSQSRVR 8496 QSQSRVR QSQSRVR 8496 User Profile = DB2
 CPF9898 : 12/03/13  09:47:02.505309
         : DB2 QSQSRVR QSQSRVR 8586 QSQSRVR QSQSRVR 8586 SERVER MODE CONNECTING JOB IS 610016/QTMHHTTP/ZENDSVR.
 MCH3401 : 12/03/13  09:47:02.505309
         : DB2 MnResolveContext PLUGILE ILERSLV 8546         *PRCLT Cannot resolve to object AINTTHER. Type and Subtype Either a system poi