Creating an RPG-based Web Service Using WDSC, Part 1
June 18, 2008 Shannon O'Donnell
Unless you’ve been hiding under a rock for the last couple of years, you cannot help but to have heard about Web Services. According to the industry experts, whoever they are, Web Services will solve every problem you have ever had and ever will have in your quest to send and receive data from one computer to another over the Web. And while that may be a bit of an overstatement, it is true that Web Services really do make communicating with another computer system on the Web very easy. In this article I am going to show you how to create a simple Web Service using Websphere Development Studio Client that will allow you to query item data from your iSeries through an RPGLE program. Requirements To get started, you need to ensure you have all of the following:
Strictly speaking, the last item is not absolutely required to complete the example shown in this article, but if you want to deploy the Web Service to your iSeries when you are done with it then you must be current on PTFs. The RPG Program The RPG program I will use as an example in this article is pretty basic. (Note: The code for the RPG program is available for download here.) It accepts four parameters, one of which is used as a look up value, the rest of which will be returned to the Web Service caller. The look up parameter will be an item number that the user will pass to your Web Service. The item number will be used to chain to a database file named ITEMP1 (source code included here), which is the item master file. If a match is found, the item master data from that record will be placed into the data structure named OutItmRecord and the IOErrFlg field and IOErrDesc fields will be filled with a “Success” message. If the item is not found in the item master file, then the IOErrFlg and the IOErrDesc fields will be marked with an error. In other words, a pretty basic RPG program. Although I used one here, you do not have to use a data structure for the output fields. You could have simply coded whatever output fields you wanted to send back to the caller as individual fields and added them to the *ENTRY PLIST. I used a data structure here for a couple of reasons. First, it’s handy to have all the output fields grouped together like this and makes it easier if you want to add other groups of data to the output later on. Second, we are going to use this data structure concept in the next article in this series that will show you how to return multiple records all at once to the caller. So it’s easier to build on this program for later if we code it correctly for more than a single use from the start. The RPG Program Example *--------------------------------------------------------------------* * PROGRAM - WSITEMLKR1 * AUTHOR - Shannon O'Donnell * PURPOSE - Interface to Web Service WsGetItems *--------------------------------------------------------------------* * NOTES: * Accepts Parameters: * * InItemNo - Item Number To Search For * IoErrFlg - Error Flag (E=Error; S=Success) * IoErrDesc - Error Message when IoErrFlg = 'E'; * Success Message when IoErrFlg = 'S'; * OutItmRecord - Record Layout of Outgoing DS Array *--------------------------------------------------------------------* FItemP1 IF E K DISK UsrOpn PREFIX(IO) D cmd PR ExtPgm('QCMDEXC') D command 2000A const D length 15P 5 const * Miscellaneous Variables d CmdString s 2000A * Web Service Required Parameters D IOErrFlg S 1a D IOErrDesc S 30a * Input Only Paramaters D InItemNo S 9a D OutItmRecord DS qualified D XItemDsc Like(IOItemDsc) D XItemPrc Like(IOItemPrc) D XItemOh Like(IOItemOh) D XItemPic Like(IOItemPic) D SDS D PgmName 1 10 D Status *STATUS D Date 276 281 0 D Time 282 287 0 D ProgramName 334 343 D ModuleName 334 343 D User 358 367 C Exsr LoadItmRec C Exsr ExitSr ******************************************************************* * LoadItmRec - Load Item Record ******************************************************************* C LoadItmRec Begsr * C InItemNo Chain Itemp1 C If %Found(ItemP1) C Eval OutItmRecord.XItemDsc = IoItemDsc C Eval OutItmRecord.XItemPrc = IoItemPrc C Eval OutItmRecord.XItemOh = IoItemOh C Eval OutItmRecord.XItemPic = IoItemPic C Eval IoErrFlg = 'S' C Eval IoErrDesc = 'Item Information Returned' C Else C Eval IoErrFlg = 'E' C Eval IoErrDesc = 'Item Not Found' C Endif C Endsr ************************************************ * Subroutine: ExitSr * * Purpose: Close all files & return * ************************************************ c ExitSr Begsr C Close Itemp1 c eval *Inlr = *On c Return c Endsr ******************************************************************* * *INZSR - Initialization Subroutine ******************************************************************* C *Inzsr Begsr * C *Entry Plist C Parm InItemNo C Parm IoErrFlg C Parm IoErrDesc C Parm OutItmRecord * * Add the Web Services library to the library list C Eval cmdString = 'ADDLIBLE LIB(WEBSVCDEMO) ' + C 'POSITION(*LAST) ' C Callp(e) cmd(CmdString:2000) C Open ItemP1 C If *In99 = *On C Read ItemP1 99 C Endif C Endsr (Note: The code shown above is available for download here.) Building the Web Service To build our Web Service, we have to do three things in WDSC:
So fire up WDSC and create a new project for yourself, giving the project a name appropriate to what we are doing here. Go ahead and change the perspective to Web as shown in Figure 1 and Figure 2.
Next we need to create a new Dynamic Web Project. To do that, click on File/New/Dynamic Web Project as shown in Figure 3.
Give your project an appropriate name. Note: This is also the name your Web Service will be known as to the outside world, so choose your name carefully. It should describe the function of your Web Service. Also, in this example I am targeting the Web Service to run on Websphere Application Server version 6.1. If you have an older version of WAS running on your iSeries, change the Target Runtime to match your own version.
You can take all the defaults on the rest of the screens by clicking the Finish button here. Creating the Java Program Call Bean Our next task is to create a new Java Program Call Bean inside the new Dynamic Web Project you just created. To do that, click on File/New/Other. In the resulting panel, as shown in Figure 5, expand the iSeries tree icon, expand the Java tree icon, and select Program Call Bean.
At this point, you could manually type in all of the program and parameter information that describes your RPG program. However, that takes too long and there is a much easier way to do it. Simply click on the Import button (Figure 6), select Remote/Local File System in the resulting window, select iSeries, and then create a new connection to your iSeries in the resulting panel (Figure 7).
Finally, drill down in your new connection to the library and source file where your RPG program is stored, and click on the program name to select it.
WDSC will now import your RPG source code and attempt to compile it. If you do not have all the files used in your library list defined in the job description for the user profile you logged on here with, you will get errors and the source will not import. To resolve this, make sure the files can be found by your user profile. When the source is finished importing, you will see a screen like the one shown in Figure 9. Select all the items in the left-hand pane and click the OK button.
Next you need to define which of the fields are input only, output only, or both. For this example, we only want the InItemNo field to be input capable. This will be the only information that the user will pass to the Web Service. Make all the other fields, including the data structure OutItmRecord output only. One other thing, unless you created the RPG program as a Service Program, make sure you change the program type for WSITEMLKR1 to *PGM. It will default to *SRVPGM when it is first imported.
Click the Next button and enter a name for the Java package that will be created. Also, and this is very important, make sure you check the Web Services box. If you do not do this, the wizard will not create the service interface Java program you will need to get your Java bean to talk to the Web Service.
Finally, you need to identify the system where the program call bean will connect to, and enter the logon values. In addition, you can also set the initial library list so the service can find your files and program(s). I usually always add the library where the RPG program is stored, but I then manually add or remove libraries from the running RPG program, by using an ADDLIBLE or RMVLIBLE command along with the QCMDEXC API in the RPG program itself. Refer to the *INZSR routine in the RPG program example code to see how that works. (Note: The RPG program example code is available for download here.)
Create the Web Service Finally it is time to create the Web Service. To do that, expand the Dynamic Web Project you created, expand the Java Resources: src tree item, and then expand the Java Program Call Bean tree item. This will be the name of your RPG program so it should be easy to find. Look for the Java source file that ends with the word “Services.java”. This source file contains the necessary Java classes to interface with a Web Service. We will use it as the basis for our Web Service. So right-click on WSITEMLKR1Services.java in this example and then click on New/Other menu items.
Now click the Show All Wizards box to get a list of all the Web Service wizards. Expand the Web Services tree item and select Web Service.
In the next panel, you can select the type of Web Service, as well as whether or not you want to test the Web Service when you are done. For now, just leave the Web Service Type at the default of “Bottom Up Java Bean Web Service.” Move your mouse over to the configuration slide bar on the left, left-click on it, and drag the slide bar up until it says “Test Service.” If you do not want to test the Web Service, then leave the slide bar at its default setting.
You can now take all of the remaining defaults to create and test your Web Service by clicking the Finish button. Note: When you click the Finish button, WDSC will now attempt to create your Web Service and to load it into the Websphere Application Server test environment. However, if the WAS test server is not yet started, the wizard will attempt to start it for you. Starting the WAS server can be a very lengthy process so you may want to get the WAS test server started when you first open WDSC. To do that, just click on the Server tab at the bottom of WDSC, click on the WAS server you are going to use, and then click the Start button/icon. If you don’t see the Servers tab, click on the Window menu item at the top of WDSC, then click on Show View and select Servers. Testing the Web Service Finally, if you elected to do so when you created the Web Service, you can test it. To run a test, click on one of the two methods created for you by the Web Service wizard. It does not really matter which one you choose. The only difference between the two is how the data is formatted for the caller when the Web Service returns.
Enter an item number that you have pre-loaded into the ITEMP1 file on your iSeries and click the GO button.
You should get the item information returned in the status window at the bottom of the screen. If you get errors, you can view them by clicking the icon that will appear in the right-hand side of your status window. The Console tab at the bottom will also be useful to help you diagnose why you are getting errors.
Next Steps You have now created your first Web Service. From here you can export the Dynamic Web Project to a J2EE EAR file and deploy it on your iSeries Websphere Application Server. The steps required to ensure that it will run on WAS on your iSeries are beyond the scope of this article, but the information on what you need to install and configure WAS on iSeries can be found on the IBM System i and i5/OS Information Center Web site. In the next article, I will show you how to build on what you learned here to return multiple records from the iSeries. Shannon O’Donnell is president of Integrated Court Technologies, LLC, and the author of hundreds of iSeries how-to articles. He can be reached at the by email through IT Jungle Contact page.
|