24
Tue, Dec
1 New Articles

The API Corner: System API Basics

APIs
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Are you as knowledgeable about APIs as you should be?

 

While it seems reasonable to assume that anyone reading RPG Developer is quite familiar with RPG, not every reader may be as familiar with the application program interfaces (APIs) available with i5/OS. In this ongoing column, "The API Corner," I will be discussing some of the wild and wonderful capabilities that are open to the RPG developer through system APIs. But the first few articles will be oriented toward the developer who, while knowledgeable about RPG, may not be that familiar with APIs.

 

i5/OS provides a significant number of system APIs that RPG developers can use. Any given API generally falls into one of these categories:

•        An i5/OS-unique interface that enables enhanced access to system capabilities

•        An industry-standard interface that enables cross-platform application compatibility with other systems (often referred to as being UNIX-type)

•        An IBM-standard interface that enables cross-platform application compatibility with other IBM systems (some of these APIs have also evolved to become industry-standard interfaces)  These IBM-standard interface APIs, depending on their age, are often referred to as being Systems Application Architecture (SAA) type, Common Execution Environment (CEE) type, or some other family-type name.

 

The initial focus of this column will be on the first type of system APIs, those that are generally unique to i5/OS. These APIs tend to have a common set of standards. These standards include basics such as parameter passing conventions, data types supported, API naming, and the like. One critical standard is related to error-handling.

 

i5/OS-unique APIs use a common parameter, known as the error-code parameter, to give the application developer control over how errors are to be reported back to the application program. This error-code parameter is variable length with two predefined structure definitions. The most frequently used structure definition has the following subfields:

•        Bytes provided-A 4-byte integer subfield (sometimes also referred to as being a 4-byte binary subfield) that is an input to the API and defines how many bytes of the error-code parameter structure are to be used by the API in reporting errors back to the developer

•        Bytes available-A 4-byte integer subfield that can be an output from the API and defines how many bytes of error-related information were returned in the error-code parameter by the API

•        Exception ID-A 7-byte character subfield that can be an output from the API and represents the *ESCAPE message ID associated with an error found by the API

•        Reserved-A 1-byte character field that is not currently used in reporting error-related information back to the application program

•        Exception data-A variable-length character subfield that can be an output from the API and may contain message-replacement data associated with the message ID returned in the Exception ID subfield

 

This error-code structure, as with most structures used by system APIs, is provided by IBM in the System Openness Includes (QSYSINC) library. If this library is not installed on your system, you need to install option 13 of i5/OS. This column will make extensive use of the QSYSINC includes in order to avoid having to duplicate API structure definitions within an article. Having said that, though, let's now examine the error-code structure that is provided in QSYSINC! The structure is found in member QUSEC of the file QSYSINC/QRPGLESRC and is shown below:

 

    D*Record structure for Error Code Parameter                       

    D****                                                          ***

    D*NOTE: The following type definition only defines the fixed      

    D*   portion of the format.  Varying length field Exception        

    D*   Data will not be defined here.                               

    D*****************************************************************

    DQUSEC            DS                                              

    D*                                             Qus EC             

    D QUSBPRV                 1      4B 0                             

    D*                                             Bytes Provided     

    D QUSBAVL                 5      8B 0                             

    D*                                             Bytes Available    

    D QUSEI                   9     15                                

    D*                                             Exception Id       

    D QUSERVED               16     16                                 

    D*                                             Reserved           

    D*QUSED01                17     17                          

    D*                                                          

    D*                                      Varying length      

 

The first field, QUSBPRV, determines how errors will be reported back to you. If this subfield is set to 0, you are telling the API to not use any of the storage defined within the error-code parameter to report errors. Instead, the API is to send the application *ESCAPE messages when a severe error is found. In this case, you will want to utilize RPG features such as defining a monitor group, the (E) extender for CALL/CALLB/CALLP operations, or an error indicator on CALL/CALLB operations. Otherwise, the application will end abnormally. Using this approach, a QUSBPRV value of 0 will allow your application to be aware that an error has been encountered, but without some extra work, you generally only know the *ESCAPE message ID, not any replacement data associated with the *ESCAPE message that was sent.

 

Another approach is to set QUSBPRV to a value of 8 or greater. This value tells the API to not send *ESCAPE messages but rather to return error-related information, up to this specified value in bytes, directly in the error-code parameter. For instance, a value of 528 tells the API that we want up to 512 bytes of message replacement data (in addition to the 16 bytes for QUSBPRV, QUSBAVL, QUSEI, and QUSERVED) returned in an error situation. In this case, we do not need to start a monitor group or utilize an (E) operations extender; no *ESCAPE will be sent to the application.

 

Clearly, the value you select for the QUSBPRV subfield is critical in terms of how you want to handle error situations. It is also critical that you remember to always set this subfield to an appropriate value. By default, RPG initializes the storage of a data structure to blanks (x'40's). If you neglect to explicitly set QUSBPRV, the subfield will default to blanks or a 4-byte value of x'40404040'. This hex value, if passed to an API and processed as an integer subfield, indicates to the API that the application has allocated 1,077,952,576 bytes of storage for the error-code parameter and that the API should feel free to return up to 1,077,952,560 bytes of message-replacement data if necessary. As the QSYSINC-provided QUSEC data structure allocates only 16 bytes of storage, any error found in an API may cause quite a bit of the application storage to be inadvertently overwritten. This situation can be very difficult to debug and is generally externalized as extremely bizarre behavior within the application. Files that were open suddenly appear to be closed, variables used in other parts of the program (or even in different programs within the same job!) have what appears to be random data in them, etc.

 

To avoid this, I recommend this approach:

 

 /copy qsysinc/qrpglesrc,qusec

                          

dErrCde           ds                  qualified          

d Common                              likeds(qusec)     

dExcpData                      512

                     

  ErrCde.Common.QUSBPRV = %size(ErrCde);  

 

This creates an instance of the error-code structure utilizing the IBM-provided definitions for the first four subfields, implements my application need to support up to 512 bytes of message replacement data, and ensures an accurate value is used for QUSBPRV.

 

The second field of the error-code data structure, QUSBAVL, represents how many bytes of error-related data were returned to the application if an error was encountered during an API call. A few points about this field are worth mentioning:

 

•        This subfield applies only to severe error situations that represent escape situations. Messages that are diagnostic, informational, or completion-oriented may be logged to the application program queue (joblog) but will not be returned via the error-code structure.

•        This subfield has significance only if the associated QUSBPRV subfield has a value of 8 or more. If QUSBPRV is set to 0, this field could be set to virtually anything as *ESCAPE messages will be sent to the application if an error is found.

•        This subfield will be 0 if no error was encountered and non-zero if a severe error was detected by the API. This subfield is the only way you should check for a severe error situation when QUSBPRV is set to 8 or more. Always first check this subfield after calling an API, with an associated QUSBPRV value of 8 or more, in order to determine if an error occurred.

•        There is no need for the application to initialize this subfield to 0 prior to calling an API. One of the first functions an API performs when called is to set QUSBAVL to 0 if QUSBPRV is 8 or more. For the application to also initialize the subfield is a waste of time.

 

QUSBAVL is the only error-code structure subfield that an API will always initialize when QUSBPRV is 8 or more. Any other field, such as QUSEI, will be left in a last-used state unless an error is encountered in the running of the API. For this reason, first check QUSBAVL for a non-zero value when an API returns. If the value is 0, then the value of QUSEI could be anything. If the value of QUSBAVL is 8 (due to QUSBPRV being set to a value of 8), then once again, QUSEI could be anything as the QUSBPRV value told the API to not update more than the first 8 bytes of the error-code structure.

 

The third subfield, QUSEI, is the exception ID corresponding to the error that the API detected. This subfield will be updated by the API when a severe error is encountered and QUSBPRV is 15 or more. While the value of QUSEI represents an *ESCAPE message, note that the prefix of the message ID returned may not necessarily be CPF. You may very well find that CPDs, along with other prefixes, are used.

 

The fifth field, QUSED01 for message-related exception data, is commented out in the QYSINC QUSEC include. This field represents a variable-length field, and you determine, based on your application requirements, what size is appropriate given the error messages and related message-replacement data the application program might want to work with. In the previous definition of the error-code data structure ErrCde, I defined the subfield ExcpData as being 512 bytes in size. I find this size to be more than adequate for 99 percent of i5/OS error messages that I'm likely to run into (that is, as long as I'm not working with the IFS and really long path names!). Note that while this subfield is variable length, the subfield is not defined as VARYING. The subfield is variable-length only in the sense that i5/OS does not predefine a fixed size. You determine the appropriate size.

 

As any given API can return a variety of error messages, I also define message-replacement data using this style:

 

dErrCde           ds                  qualified                       

d Common                              likeds(qusec)                   

dExcpData                      512                                    

                                                                       

dCPF2101          ds                  qualified based(ExcpData_Ptr)   

d ObjTyp                         7                                    

                                                                      

dCPF9810          ds                  qualified based(ExcpData_Ptr)   

d LibNam                        10                                    

                                                                      

dCPF9812          ds                  qualified based(ExcpData_Ptr)   

d FilNam                        10                                    

d LibNam                        10                                    

                                                                      

  ErrCde.Common.QUSBPRV = %size(ErrCde);                              

  ExcpData_Ptr = %addr(ErrCde.ExcpData);

                              

  // Call a System API using the ErrCde Error code parameter and a

  // ErrCde.Common.QUSBPRV = 528 as set above.

  //

  // We will assume that the API might return CPF2101, CPF9810, or

  // CPF 9812 - each API documents those escape messages it might

  // return in the Information Center.  After calling the API:

  if (ErrCde.Common.QUSBAVL > 0);                                    

     select;                                                          

        when ErrCde.Common.QUSEI = 'CPF2101';                        

             dsply ('Invalid object type ' + %trimr(CPF2101.ObjTyp) +

                    '.');                                             

        when ErrCde.Common.QUSEI = 'CPF9810';                        

             dsply ('Library ' + %trimr(CPF9810.LibNam) +            

                    ' not found.');                                  

        when ErrCde.Common.QUSEI = 'CPF9812';                        

             dsply ('File ' + %trimr(CPF9812.FilNam) +               

                    ' not found in ' + %trimr(CPF9812.LibNam) + '.');

        other;                                                       

             dsply ('Unexpected message ' + ErrCde.Common.QUSEI +    

                     ' received.');                                  

     endsl;                                                          

  endif;                                                              

 

I find that using qualified, based data structures that are unique to each message makes my code much easier to review and maintain. And I assure you that I do have more robust error-handling in my production code than this simple example using DSPLYs. But this should give you the general idea! In order to determine how each message-related data structure (such as CPF9812 above) should be defined, use the Display Message Description (DSPMSGD) command with option 1 (Display message text) and option 2 (Display field data).

 

With this brief introduction to system API error-handling and some of the conventions I will be using in future articles, we are now ready to jump into the wonderful world of RPG and APIs. Keep an eye out for future editions of RPG Developer.

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: