On the eve of this historic event – the Inauguration of Barack Obama as our 44th President – I thought it only fitting to provide a post that combined PowerBuilder with Politics… The web service in question serves up a random quote from our incomparable, (and soon to be unemployed) 43rd President, George W. Bush.
This entry will show you how easy it is to consume a web service using the .NET web services engine within PB11.5.
Step 1. Get yourself some WSDL
The language of SOAP-based web services is WSDL, or Web Services Descriptor Language. This highly arcane XML syntax contains the entire description of a web service, from the methods it exposes to the datatypes of the parameters it accepts and returns. Most web service engines will serve up the WSDL for their service by simply adding ?WSDL to the end of the URL. For example, we’ll be using the service at http://greg.froh.ca/fun/random_bushism/.
To see the WSDL, use this link: http://greg.froh.ca/fun/random-bushism/soap/?wsdl
(Save that last URL to your clipboard, you’ll need it in step 2 below…)
Step 2. Build a Web Services Proxy
PB11.5 ships with a sample Web Services application. I’ll add the Random Bushisms web service to that application, since it already has most of the app infrastructure in place. That workspace can be found in
C:\Documents and Settings\All Users\Documents\Sybase\PowerBuilder 11.5\Code Examples\Web Services.
To create a web services proxy, select File * New. In the Project tab, select Web Service Proxy, as shown in image #1.
The Web Services Proxy project object consists of two tabs – General and Web Service.
Let’s start with the General tab.
Deployment PBL: This is where PB will generate the Proxy class, so you’re selecting a PBL. The best practice (and the standard followed in the example workspace) is to create a PBL specifically for Proxy classes.
Proxy Name Prefix: This allows you to set your naming conventions for the proxy classes and their associated artifacts. I prefer “s” (for service) followed by a sequential number and an underscore. For the Bushism service, I used the prefix s21_
Now on to the Web Service tab (image 2 above).
The top field is the WSDL location, and you have two choices. You can either paste in a URL to web services WSDL somewhere out on the internet, or you can click the button with the elipses to select a file on your local file system that has a .WSDL extension. In our case, we’re using a public service, so paste in http://greg.froh.ca/fun/random_bushism/soap/?WSDL. (I told you that you’d need it…)
Note: If this URL is unreachable or returns an error, I’ve included the .WSDL file in the PB115_webservices.zip file, which can be downloaded from http://blogs.sybase.com/phoran/wp-content/uploads/2009/03/pb115_webservices.zip. PH
The next step is to click the Services… button. This causes PB to introspect the WSDL file, and bring back this nice graphical treeview dialog containing the methods and structures contained in the WSDL. Here’s what that dialog looks like:
Trust me – be thankful for this dialog. You don’t want to have to read that WSDL syntax yourself… What you’re doing in this dialog is selecting the service’s methods that you want to expose through the proxy. And, if those services return structures instead of simple datatypes as parameters, you’ll select the corresponding structures as well. This service is fairly simple – there’s one method: RandomBushismService, and one structure: RandomBushism.
Finally, in the WSDL Engine box, select the .NET engine, and provide a name for the .NET assembly DLL that will be generated. Click Save to save the project definition, and click Deploy to create the proxy. You should see two new entries in the Proxies PBL.
s21_randombushismservice: This is the proxy itself. You can open it and see the exposed method “getRandomBushism()”.
s21_randombushism: This is an NVO with two public instance variables – Bushism and Context, which represents the structure returned from the web service call.
Step 3. Create a visual interface to display the results.
In the tabpages.pbl file, the ancestor class uo_ancestor contains all the plumbing to instantiate the service proxy. All you need to do is provide the invocation code, and then process the output. Since the service returns two strings – the quote itself, and the corresponding context in which it was said, I created a simple layout with two statictext controls.
In the clicked event of the Invoke button, add the following code:
if instantiateService(px_Service, "s21_randombushismservice") then
lstr_bushism = px_Service.getRandomBushism( )
st_bushism.text = lstr_bushism.bushism
st_context.text = lstr_bushism.context
CATCH (Throwable t)
MessageBox("Invocation Error", t.GetMessage(), StopSign!)
It couldn’t be simpler. Instantiate the proxy class, invoke the method, use the results…
Save the object into the tabpages.PBL as uo_bushisms. The instantiateService() method is defined in the ancestor class uo_ancestor, so browse that at your discretion.
Step 4. Add the new service definition to the Service treeview.
The final step hooks this all together and allows the application to run with our changes. This isn’t really a requirement to get Web Services working from PB, it’s just to get them callable from this particular application. The main treeview is driven from a datawindow whose resultset is hard-coded into the .data attribute.
In the ws.pbl file, open the datawindow d_svclist.
If the Data pane is not visible, select View * Data, then go to the Data tab.
Insert a new row, and add the following column values (these can be copied and pasted from here):
svcname: Random Bushism
svcdesc: Retrieve a random George Bush quotation
svcimpl: Microsoft .NET
Save the datawindow, then try running it!
I’ve uploaded the workspace with all these revisions intact into the PB115_webservices.zip file.