"Preliminary" steps in Powerbuilder
This section describes the steps to follow in order to invoke a Web Service.
- Create a new PBL to hold the objects that will be created, especially if you just want to "play around". In this example it will be SAPDS.PBL.
- Create a new object: on the "Project" tab, select "Web Service Proxy Wizard"
- Check the "Use .Net Engine" checkbox, click Next.
- Indicate the WSDL file URL (see above) and the Assembly Name (e.g. SAPDataServices_Server.dll), then click NEXT.
Note that the Windows SDK for .Net Framework 4.0 must be installed on your system. If that is not the case, you have to do that first:
See the Troubleshooting section further down, if you have issues with this step. - Select a Service, e.g. "WebService.connection_Operations, click Next
- In the next step, you may set the prefix for the proxy.
The wizard says that by default, it is the portname for each port, but you may leave it empty. In the near future we may decide to set up a naming convention rule for this step. - Specify the project name and the library where it will be stored:
- You may verify your settings on the "Ready to Create Proxy" window before hitting Finish:
Note that the documentation states that "the assembly is generated in the current target directory". - After that, the proxy should be created. Clicking on the "Services..." button opens a window showing the services and structures.
- In the PBL, right-click the generated proxy (e.g. p_ws_sapds) and select "Deploy" to generate the Services and Structures in the PBL:
Invoking Web services through SOAP requires serialization and deserialization of datatypes, and the building and parsing of XML-based SOAP messages.The pbwsclient125.pbx file contains objects for the .NET Web service engine that enable you to perform these tasks without extensive knowledge of the SOAP specification and schema, the XML Schema specification, or the WSDL specification and schema. You can use these objects after you import the extension file into a PowerBuilder Web service application. - At this point it might be necessary to import a Powerbuilder extension file that should be located in "C:\Program Files (x86)\Sybase\Shared\pbwsclient125.pbx".
Right-click the PBL, select "Import PB Extension..." and select the PB extension file indicated above.
The above are necessary "preliminary" steps, next we'll look at the Powerbuilder code needed to actually invoke a Web Service.
Powerbuilder code to invoke a Web Service
In order to verify the above steps, i.e. to test the Web Service(s), I created a function (f_ws_logon) in a new NVO (n_sap_ds_func) that is invoked through a button click in a very basic window (w_sapds_main).
These objects can be found in the attached PBL (the code was created just to prove the concept, so no need to discuss the naming nor code quality).
In the next section, the code is presented and some additional information given.
connection_operations lnv_conn session lnv_ws_session logonrequest lnv_log_req runbatchjobrequest lnv_runbatchjobreq_HED, lnv_runbatchjobreq_DDO batchjobresponse lnv_batchjobresp_HED, lnv_batchjobresp_DDO batch_job_admin lnv_batch_jobadm batch_jobs lnv_batch_jobs soapconnection lnv_soap_conn soapexception lnv_soap_exc runbatchjobrequestvariable lnv_runbatchreqvar job_webservice_call_poc_globalvariables lnv_globvar integer li_val, li_val2, li_val3 boolean lb_sess // lnv_batch_jobadm = CREATE batch_job_admin lnv_batch_jobs = CREATE batch_jobs lnv_log_req = CREATE logonrequest lnv_runbatchjobreq_HED = CREATE runbatchjobrequest lnv_runbatchjobreq_DDO = CREATE runbatchjobrequest lnv_batchjobresp_HED = CREATE batchjobresponse lnv_batchjobresp_DDO = CREATE batchjobresponse lnv_globvar = CREATE job_webservice_call_poc_globalvariables |
Next, set some values and the Web Service parameters
// set values lnv_log_req.username = 'zzzzz' lnv_log_req.password = 'aaaaa' lnv_log_req.cms_authentication = 0 // secEnterprise = 0, secLDAP = 1, secWinAD = 2, secSAPR3 = 3, lnv_log_req.cms_system = 'srvsapbodst01' // sample Web Service by DDO lnv_runbatchjobreq_DDO.jobname = "JOB_WEBSERVICE_CALL_POC" lnv_runbatchjobreq_DDO.reponame = "BOXI_DS4_LOCAL_DDO" lnv_globvar.g_countermax = "2000000" // at test revealed that the web services are apparently executed asynchronously // sample Web Service by DHE lnv_runbatchjobreq_HED.jobname = "JOB_OpenHub_Test" lnv_runbatchjobreq_HED.reponame = "BOXI_DS4_LOCAL_DHE" |
Finally, the Web Service is called.
As noted in the comment above, the Web Service is apparently called asynchronously (the fact that there is a "cancelasync" method further supports this assumption). |
Note the comments in the code, as they provide some important additional information!
// call the Web Service TRY li_val = lnv_soap_conn.createinstance(lnv_conn, "connection_operations") li_val2 = lnv_soap_conn.createinstance(lnv_batch_jobadm, "batch_job_admin") // HED li_val3 = lnv_soap_conn.createinstance(lnv_batch_jobs, "batch_jobs") // DDO IF li_val = 0 THEN // 0 means OK (in this example li_val, li_val2 and li_val3 all returned 0) // OK lnv_ws_session = lnv_conn.logon(lnv_log_req) // log on to get session lb_sess = lnv_batch_jobadm.setsessionvalue(lnv_ws_session) // set the session value for the next call(s) lnv_batchjobresp_HED = lnv_batch_jobadm.run_batch_job(lnv_runbatchjobreq_HED) // call Web Service / HED lnv_batchjobresp_DDO = lnv_batch_jobs.job_webservice_call_poc(lnv_globvar) // call Web Service / DDO // display error message (HED) IF lnv_batchjobresp_HED.pid = -1 THEN Messagebox("Web Service error", lnv_batchjobresp_HED.errormessage + ', repository name: ' + lnv_batchjobresp_HED.reponame) END IF // display error message (DDO) IF lnv_batchjobresp_DDO.pid = -1 THEN Messagebox("Web Service error", lnv_batchjobresp_DDO.errormessage + ', repository name: ' + lnv_batchjobresp_DDO.reponame) END IF ELSE // Not OK // (add appropriate error handling) END IF CATCH (runtimeerror exc) MessageBox ("WS Runtime Error", exc.text) FINALLY // Messagebox("try... catch", "finally clause", Information!, OK!) END TRY |
The remaining code doesn't add much (destroying the created objects), so it's been left out for better lisibility.
The above code, invoking the indicated Web Services, succeeded in the case of the DDO Web Service:
The HED Web Service was invoked, but returned an error message:
The LOGON call was obviously successful as it returned the needed session ID.
Session ID
If the session Id is not provided when calling an SAP Data Service Web Service, the following error message will be displayed (see the CATCH clause):
Debugging a Web Service
Please refer to the article Debugging a Web Service using Fiddler for some very useful information regarding debugging (but not only) a Web Service call.
Troubleshooting
Installation of the "Windows SDK for Windows 7 and .NET Framework 4" failed on my system for no apparent reason:
The indicated file "Samples\Setup\HTML\ConfigDetails.htm" was not available. In fact, nothing remained after the failed installation, apparently the installation process deleted all copied/installed files.
The solution was to install the freely available "Microsoft Visual Studio 2010 Express", because that installs the needed .NET framework.