- Extension ID
- What's new?
- Description
- Supported languages
- Function Point, Quality and Sizing support
- Compatibility
- Download and installation instructions
- Prepare and deliver the source code
- Deliver the source code
- Analysis configuration
- What results can you expect?
- Known limitations
Summary: This document provides information about the extension providing RPG support.
Extension ID
com.castsoftware.rpg
What's new?
Description
This extension provides support for applications written using RPG languages and/or CL languages.
Supported languages
- RPG III (also known as GAP 3)
- RPG IV (fixed-form and free format)
- CL
Function Point, Quality and Sizing support
- Function Points (transactions): a green tick indicates that OMG Function Point counting and Transaction Risk Index are supported
- Quality and Sizing: a green tick indicates that CAST can measure size and that a minimum set of Quality Rules exist
Function Points (transactions) | |
---|---|
Quality and Sizing |
Compatibility
CAST Imaging Core release | Supported |
---|---|
8.3.x |
Download and installation instructions
The extension will be automatically downloaded and installed in CAST Console when at least one RPG type file is delivered for analysis. You can manage the extension using the Application - Extensions interface.
Prepare and deliver the source code
When the extension is downloaded and installed, you can now package your source code and run an analysis. The process of preparing and delivering your source code is described below:
Source code preparation
Before the RPG source code can be delivered and then analyzed, it needs to be collected from the proper iSeries libraries and transferred to the designated location. During this operation, each artifact (program, CL, DSPF) must be put into a single file only. This will result in a single artifact per file. Furthermore, the type of source code must be expressed using the extension to the file. The appropriate file extensions are listed in the following table.
Source code is kept in a member of a file. The file is kept in a library. Each file can have many members. Each member is the source code for a program. The source code files can have any name but conventionally the names start with Q and end with SRC, for source.
Source code type | iSeries library | Required extension | Used in MetaModel |
---|---|---|---|
RPG-III programs | QRPGSRC | *.rpg, *.rpg38 | RPG300 |
ILE RPG Programs | QRPGLESRC | *.rpgle | RPG400 |
ILE RPG Programs with SQL | QSQLRPGLESRC | *.sqlrpgle | RPG400 |
Copy source members | QCPYLESRC | *.cpyle | RPG400 |
CL programs | QCLSRC | *.cl, *.clp, *.cl38, *.clp38 | CL400 |
ILE CL Programs | QCLLESRC | *.clle | CL400 |
Display Files | QDDSSRC | *.dspf, *.dspf38 | DDS400 |
Printer Files | QDDSSRC | *.prtf, *.prtf38 | DDS400 |
Logical Files | QDBSRC | *.lf, *.lf38 | SQL Analyzer/DDS400 |
Physical Files | QDBSRC | *.pf, *.pf38 | SQL Analyzer/DDS400 |
What about IBM Db2 for i source code?
In previous releases of the RPG Analyzer extension, when IBM Db2 for i source code was delivered, a dedicated extraction process was launched within the RPG Analyzer to transform this source code into a format that could be analyzed. Starting in release ≥ 3.1.x, the RPG Analyzer is no longer responsible for analyzing source code from IBM DB2 for i. Instead, this task is undertaken by the com.castsoftware.sqlanalyzer (release ≥ 3.5.4 is required).
There is no change to source code delivery process when using AIP Console - the IBM DB2 for i source code should be delivered together with the RPG source code and AIP Console will be able to detect this type of source code and create the necessary Analysis Units. For those using legacy CAST Management Studio/Delivery Manager Tool, the source code delivery process has changed and is explained below.
IBM Db2 for i is also known as DB400.
Deliver the source code
Using CAST Console
RPG is supported in CAST Console ≥ 1.22.
Note about using RPG ≥ 3.1.0 with AIP Console 1.22, 1.23, 1.24 and 1.25
RPG ≥ 3.1.0 does not function correctly with CAST Console 1.22, 1.23, 1.24 and 1.25, however, a workaround exists. Before delivering your source code, locate the following file on the AIP Node that will be performing the analysis:
%PROGRAMDATA%\CAST\AipConsole\AipNode\code-scanner-config.xml
Edit the file and remove or comment out the following section:
<package packageType="dmtdb400techno.DB400Package" extractorType="dmtdb400extractor.DB400Extractor" deliveryFile=".lf;.pf;.sqli;.sqlt;.sqlv;.sqlu;.sqlp" deliveryData="COE"/>
Save the file and restart the AIP Node.
CAST Console expects either a ZIP/archive file or source code located in a folder configured in AIP Console. You should include in the ZIP/source code folder all RPG and IBM DB2 for i (if present) source code. CAST highly recommends placing the files in a folder dedicated to RPG. If you are using a ZIP/archive file, zip the folders in the "temp" folder - but do not zip the "temp" folder itself, nor create any intermediary folders:
D:\temp |-----RPG |-----OtherTechno1 |-----OtherTechno2
When the source code has been delivered, CAST Console will create an Analysis Unit for:
- IBM Db2 for i (if present)
- RPG
Analysis configuration
Add a dependency between the RPG Analysis Unit as Source and SQL Universal Analysis Unit as the target:
Configuring Technical Size measures for RPG in the CAST Health Dashboard
Technical Size measures can be displayed for RPG analysis results in the CAST Health Dashboard by manually editing the following file:
1.x WAR file: %CATALINA_HOME%\webapps\<dashboard>\portal\resources\app.json 2.x WAR file: %CATALINA_HOME%\webapps\<dashboard>\WEB-INF\classes\config\hd\app.json 2.x ZIP file: com.castsoftware.aip.dashboard.2.0.0\config\hd\app.json
Add the following entries into the existing section "TechnicalSizeMeasures":
"TechnicalSizeMeasures": { ... { "id": 1008000, "label": "Number of RPG400 Program(RPG400)" }, { "id": 1008001, "label": "Number of RPG400 Subroutine(RPG400)" }, { "id": 1008002, "label": "Number of RPG400 Procedure(RPG400)" }, { "id": 1008003, "label": "Number of RPG IV Copy Member(RPG400)" }, { "id": 1009000, "label": "Number of RPG300 Program(RPG300)" }, { "id": 1009001, "label": "Number of RPG300 Subroutine(RPG300)" }, { "id": 1009003, "label": "Number of RPG300 Copy Member(RPG300)" } }
Following any changes you make, save the app.json file and then restart your application server so that the changes are taken into account.
What results can you expect?
Links
C SCRLVL CHAIN PACCLVS C IF %FOUND C DELETE RACCLV C ENDIF
CALL PGM(&EXTLIB/&EXTPGM)
DataQ CL example
/*********************************************************************/ /* QSNDDTAQ and QRCVDTAQ example for DataQ */ /*********************************************************************/ PGM DCL VAR(&DQNAME) TYPE(*CHAR) LEN(10) VALUE('FILEINFO') DCL VAR(&DQLIB) TYPE(*CHAR) LEN(10) VALUE('QGPL') DCL VAR(&DQSNDLEN) TYPE(*DEC) LEN(5 0) VALUE(14) DCL VAR(&DQLEN) TYPE(*DEC) LEN(5 0) DCL VAR(&DQSNDDATA) TYPE(*CHAR) LEN(100) DCL VAR(&DQDATA) TYPE(*CHAR) LEN(100) DCL VAR(&DQWAIT) TYPE(*DEC) LEN(5 0) VALUE(0) CHGVAR VAR(&DQSNDDATA) VALUE('THIS IS A TEST') CALL QSNDDTAQ PARM(&DQNAME &DQLIB &DQSNDLEN &DQSNDDATA) CALL QRCVDTAQ PARM(&DQNAME &DQLIB &DQLEN &DQDATA &DQWAIT) SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(&DQDATA) ENDPGM
IBM MQ CL example
CALL PGM(QMQMSAMP/AMQ3GET4) PARM('Queue_Name','Queue_Manager_Name')
CALL PGM(QMQMSAMP/AMQ3PUT4) PARM('Queue_Name','Queue_Manager_Name')
SQL CL examples
exec sql update vrtfilep set vrupdf = ' ' where vrupdf <> ' ';
PGM RUNSQL SQL('PREPARE MYSTMT FROM SELECT * FROM VIEWSQ') ENDPGM
SQL Script CL examples
PGM RUNSQLSTM SRCFILE(CGSRC/QSQLSRC) SRCMBR(S_REQ46) + COMMIT(*NC) ENDPGM
Note
The callLink between "CL Call to Sql File" and "SQL Script" is created by the com.castsoftware.wbslinker (≥ 1.7.30).
SQL RPG fix format example
PDelFactArc b Export /Free W_Requete = 'Select * From Viewsq'; /End-Free C/Exec Sql C+ Prepare S1 From :W_Requete C/End-Exec PDelFactArc e
SQL RPG free format example
SqlStmt = 'Select * From Viewsq'; Exec Sql Prepare p1 From :SqlStmt ;
RPG IV Missing Physical/Logical File
In absence of Table/View with name matching:
In presence of Table/View with name matching:
The RPG IV Missing Physical/Logical File "APAGLQUA" object is created at analyzer level because com.castsoftware.rpg cannot know at that point that a Table or View exists resulting from a com.castsoftware.sqlanalyser analysis. At application level, a matching protocol is used to link "RPG IV File Disk" to the "Table" and delete the RPG IV Missing Physical/Logical File only if a match has been found.
DataQ RPG example
I 'INKOOP ' C DTAQ IINKOOP DS I 1 3 CTRL I 4 9 BLVNR C *ENTRY PLIST C PARM PLVNR 6 C PARM DTAQL 10 C MOVEL'BEL' CTRL C MOVELPLVNR BLVNR C CALL 'QSNDDTAQ' C PARM DTAQ PDTAQ 10 C PARM DTAQL PDTAQL 10 C PARM 9 LEN 50 C PARM INKOOP C MOVE *ON *INLR C RETRN
d DQLib s 10 inz('*LIBL') d DQName s 10 inz('CONVMAIL') d DQLen s 5 0 inz(512) *********************************************************************** c snddtq begsr c call 'QSNDDTAQ' c parm DQName c parm DQLib c parm DQLen c parm DQData c endsr ***********************************************************************
dcl-pr QSNDDTAQ extpgm ; *n char(10) const ; //Data queue name *n char(10) const ; //Library *n packed(5) ; //Length of data *n char(100) ; //Data end-pr ; for QData.Counter = 1 to 10 ; QData.Field1 = %char(QData.Counter) ; QData.Field2 = %char(QData.Counter * 10) ; QData.Field3 = %char(QData.Counter * 100) ; QSNDDTAQ('TESTDTAQ':'MYLIB':LengthOfData:QData) ; endfor ;
dcl-pr QSNDDTAQ extpgm ; *n char(10) const ; //Data queue name *n char(10) const ; //Library *n packed(5) ; //Length of data *n char(100) ; //Data end-pr ; BegSr srDTAQ; CALLP(e) QSNDDTAQ('TESTDTAQ':'MYLIB':LengthOfData:QData); EndSr;
IBM MQ RPG example
001 C EVAL ODON = TestQueue UTT07R P GetEqMsg B export UTT07R UTT07R ** Procedure interface UTT07R ** ------------------- UTT07R D GetEqMsg PI 12000A UTT07R D Queue 48A value UTT07R D Remove 1A value options(*nopass) UTT07R D WaitMillis 10I 0 value options(*nopass) UTT07R UTT07R ** Local variables UTT07R ** --------------- UTT07R UTT07R * The last-used queue, held in static storage for persisitence over calls UTT07R D LastQueue S like(Queue) static UTT07R UTT07R * Local error code UTT07R D GetError S 4A UTT07R UTT07R * 0Reply from user if there is an error UTT07R D Reply S 1A UTT07R UTT07R * Alpha versions of reason code UTT07R D ReasonA DS 9 UTT07R D ReasonA4 1 4A UTT07R UTT07R * The data returned from MQSeries UTT07R D MQMessage S 12000A UTT07R UTT07R * Has there been a handle error UTT07R D HandleErr S 1A UTT07R UTT07R ** Parameter lists UTT07R ** --------------- UTT07R UTT07R * MQ get message from queue (receive message) UTT07R C PLMQGET PLIST UTT07R C PARM CID UTT07R C PARM HCONN UTT07R C PARM HOBJ UTT07R C PARM MQMD UTT07R C PARM MQGMO UTT07R C PARM BUFLEN UTT07R C PARM MQMessage UTT07R C PARM MESLEN 9 0 UTT07R C PARM CCODE UTT07R C PARM REASON UTT07R UTT07R ** Procedure processing UTT07R ** -------------------- UTT07R UTT07R * Connect to the queue manager to ensure connection UTT07R C Eval ReasonA4 = ConnectMQM( QueueManager ) UTT07R UTT07R * If the connection failed dump and exit UTT07R B001 C if ReasonA4 <> *blanks UTT07R 001 C dump UTT07R 001 C return GET_ERROR UTT07R E001 C ENDif ReasonA4 <> *bUTT07R UTT07R * Open MQSeries queue UTT07R C eval ReasonA4 = OpenQueue( Queue ) UTT07R UTT07R * If the called procedures reported an error, dump and exit UTT07R B001 C if ReasonA4 <> *blanks UTT07R 001 C dump UTT07R 001 C return GET_ERROR UTT07R E001 C ENDif ReasonA4 <> *bUTT07R UTT07R * Use the queue name to get the MQSeries object handle UTT07R C eval HOBJ = GetHandle( Queue ) UTT07R UTT07R * Set up the options for an MQGET call UTT07R UTT07R * Set to 'Get Message' UTT07R C Z-ADD MQGET CID
The value of the parameter ODON is evaluated. This parameter holds the name of the queue. Here are three examples of how the name of the queue can be declared.
D TestQueue S 10 INZ('TESTQUEUE ') UTT07R 001 C EVAL ODON = TestQueue UTT07R
001 C EVAL TestQueue = 'TESTQUEUE' UTT07R 001 C EVAL ODON = TestQueue UTT07R
001 C EVAL TestQueue = $TESTQUEUE UTT07R 001 C EVAL ODON = TestQueue UTT07R
If there is no file in the application where $TESTQUEUE is declared, we create an unknown queue object.
REST RPG examples
Support of http_get, http_put, http_post, http_delete APIs : example for http_get API
/free url = 'http://example.com:8500/cust'; rc = http_get(url: options); if (rc<>1 and rc<>500); http_crash(); endif; if rc=500; xml-into errMsg %xml(stmf: 'path=error doc=file'); dsply errMsg; else; xml-into custInfo %xml(stmf: 'path=result/cust doc=file'); dsply custInfo.name; dsply custInfo.street; dsply ( custInfo.city + ' ' + custInfo.state + ' ' + custInfo.postal ); endif; unlink(stmf); *inlr = *on; /end-free
Support of http_string API
dcl-proc translate; ... url = 'https://gateway.platform.net/language-translator/api' + '/v3/translate?version=2018-05-01'; monitor; response = http_string('POST': url: request: 'application/json'); http_error(*omit: httpstatus); httpcode = %char(httpstatus); on-error; httpcode = http_error(); endmon; ... end-proc;
Support of http_url_get and http_url_post APIs : example for http_url_get API
/free url = 'http://rss.test.com/rss/test.rss'; filename = 'http_file.xml'; rc = http_url_get( url : filename ); if (rc <> 1); PrintLine = http_error(); except; unlink(filename); return; endif; /end-free
REST services with Embedded SQL
dcl-proc translate; url = 'http://example.com:8500/cust'; exec SQL select SYSTOOLS.HTTPPOSTCLOB(:url, :hdr, :request) into :response from SYSIBM.SYSDUMMY1; end-proc;
dcl-proc translate; url = 'http://example.com:8500/cust'; ... exec SQL values QSYS2.HTTP_GET(:url, :hdr, :request) into :response from SYSIBM.SYSDUMMY1; end-proc;
IBM-supplied AXISC routines
Support of AXISC routine : axiscTransportSetProperty API with AXISC_PROPERTY_HTTP_METHOD parameter
dcl-proc translate; dcl-s url varchar(2000); dcl-s request varchar(2000); dcl-s response varchar(5000); dcl-s rcvBuf char(5000); dcl-s rc int(10); dcl-s propName char(200); dcl-s propVal char(200); dcl-s transportHandle pointer; userid = 'apikey'; password = '8OD0RY71zMwXjkNiBLzTN8i848R9wXMOmADjuvoKY2zw'; url = 'https://gateway.platform.net/language-translator/api' + '/v3/translate?version=2018-05-01'; transportHandle = axiscTransportCreate(url: AXISC_PROTOCOL_HTTP11); if (transportHandle = *null); failWithError(transportHandle: 'axiscTransportCreate'); endif; propName = 'POST' + x'00'; axiscTransportSetProperty( transportHandle : AXISC_PROPERTY_HTTP_METHOD : %addr(propName)); end-Proc;
Objects
CL400
Icon | Object Name |
---|---|
CL Program | |
CL Project | |
CL Subroutine | |
CL Call to Generic Program | |
CL EXEC SQL | |
CL Call to Sql File | |
CL Data Queue Publisher | |
CL Data Queue Receiver | |
CL Data Unknown Queue Publisher | |
CL Data Unknown Queue Receiver | |
CL IBM MQ Queue Publisher | |
CL IBM MQ Queue Receiver | |
CL IBM MQ Unknown Queue Publisher | |
CL IBM MQ Unknown Queue Receiver |
DDS400
Icon | Object Name |
---|---|
DDS Project | |
DDS Section | |
DDS Printer File | |
DDS Display File | |
DDS Join Structure | |
DDS Logical File | |
DDS Physical File | |
DDS Record Structure LF | |
DDS Record Structure PF |
RPG 300
Icon | Object Name |
---|---|
RPG III Project | |
RPG III Program | |
RPG III MainSubroutine | |
RPG III Subroutine | |
RPG III File Printer | |
RPG III File Disk | |
RPG III File Workstn | |
RPG III File Special | |
RPG III File Seq | |
RPG III Copy Member | |
RPG III SQL Statement/Structure | |
RPG III Procedure | |
RPG III Call to Generic Program | |
RPG III EXEC SQL | |
RPG III Missing Copy Member | |
RPG III Missing Physical/Logical File | |
RPG III Missing Display File | |
RPG III Missing Printer File | |
RPG III Data Queue Publisher | |
RPG III Data Queue Receiver | |
RPG III Data Unknown Queue Publisher | |
RPG III Data Unknown Queue Receiver | |
RPG III IBM MQ Queue Publisher | |
RPG III IBM MQ Queue Receiver | |
RPG III IBM MQ Unknown Queue Publisher | |
RPG III IBM MQ Unknown Queue Receiver |
RPG 400
Icon | Object Name |
---|---|
RPG IV Project | |
RPG IV Program | |
RPG IV MainSubroutine | |
RPG IV Subroutine | |
RPG IV File Printer | |
RPG IV File Disk | |
RPG IV File Workstn | |
RPG IV File Special | |
RPG IV File Seq | |
RPG IV Procedure | |
RPG IV Procedure Prototype | |
RPG IV Copy Member | |
RPG IV Call to Generic Program | |
RPG IV EXEC SQL | |
RPG IV Module | |
RPG IV Missing Copy Member | |
RPG IV Missing Physical/Logical File | |
RPG IV Missing Display File | |
RPG IV Missing Printer File | |
RPG IV Missing Procedure | |
RPG IV Data Queue Publisher | |
RPG IV Data Queue Receiver | |
RPG IV Data Unknown Queue Publisher | |
RPG IV Data Unknown Queue Receiver | |
RPG IV IBM MQ Queue Publisher | |
RPG IV IBM MQ Queue Receiver | |
RPG IV IBM MQ Unknown Queue Publisher | |
RPG IV IBM MQ Unknown Queue Receiver | |
RPG IV Get Resource Service | |
RPG IV Post Resource Service | |
RPG IV Put Resource Service | |
RPG IV Delete Resource Service |
Analysis messages
RPG-001
Identifier | RPG-001 |
---|---|
Message | Cannot resolve copy ... |
Severity | Warning |
Explanation | Analyser could not find the source file included by a /copy statement. This can lead to various missing results. |
User Action | Ensure that all required source code is packaged and delivered. |
RPG-002
Identifier | RPG-002 |
---|---|
Message | Cannot resolve DDS file ... |
Severity | Warning |
Explanation | Analyser could not find a DDS file (pf, lf, dspf, prtf, ...) |
User Action | Ensure that all required source code is packaged and delivered. |
RPG-003
Identifier | RPG-003 |
---|---|
Message | Cannot resolve program ... |
Severity | Warning |
Explanation | Analyser could not find a program. |
User Action | Ensure that all required source code is packaged and delivered. The program can also be in a different technology (COBOL, etc...) in that case it will be linked in a latter analysis step. |
RPG-004
Identifier | RPG-004 |
---|---|
Message | Cannot resolve procedure ... |
Severity | Warning |
Explanation | Analyser could not find a procedure. |
User Action | Ensure that all required source code is packaged and delivered. |
Structural Rules
The following structural rules are provided:
Known limitations
- SOAP services are not supported
- In RPG
- Dynamic calls are not supported
- Dynamic SQL is partially supported since 3.3.0-alpha2 ('prepare' and 'execute immediate' with variables are resolved when encountered in RPG IV free format; the support for RPG IV fixed format and CL is available since 3.3.0-alpha3)