This document extends on my prior example SAP web services: http://scn.sap.com/docs/DOC-38805 and http://scn.sap.com/docs/DOC-38764. The difference in this example, is that here we are creating a web service consumer. In a real world scenario, this would be calling an external web service from within the SAP environment.
Step 1.
A Web Service is needed which is external to SAP. Either create one or make sure one is made available to you. All you need is some WSDL URL. I chose to create my own in VB.NET. This web service retrieves the email address from an LDAP directory based upon the user ID passed into the service.
My WSDL: http://10.16.16.86/HelloWorld_WS/WebService2.asmx?WSDL
Example below:
Public Class WebService2
Inherits System.Web.Services.WebService
Const ADS_SCOPE_SUBTREE = 2
Dim objConnection = CreateObject("ADODB.Connection")
Dim objCommand = CreateObject("ADODB.Command")
Dim objRecordSet = CreateObject("ADODB.Recordset")
Structure TestStruct
Dim EmpID As String
Dim EmpEmail As String
End Structure
<WebMethod()> _
Public Function GetMailAddress(ByVal str_UserID As String) As TestStruct()
objConnection.Provider = "ADsDSOObject"
objConnection.Properties("User ID") = "<domain>\<user account>"
objConnection.Properties("Password") = "<password>"
objConnection.Open("Active Directory Provider")
objCommand.ActiveConnection = objConnection
If str_UserID = "00000000" Then
objCommand.CommandText = "SELECT userAccountControl, samAccountName, mail" & _
" FROM 'LDAP://<IP ADDRESS>/OU=<GROUP>,dc=<DOMAIN>' WHERE objectClass='user'"
Else
objCommand.CommandText = "SELECT userAccountControl, samAccountName, mail" & _
" FROM 'LDAP://<IP ADDRESS>/OU=<GROUP>,dc=<DOMAIN>' WHERE objectClass='user'" & _
" and samAccountName=" & "'" & str_UserID & "'"
End If
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Timeout") = 30
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.Properties("Cache Results") = False
objRecordSet = objCommand.Execute
Dim Test() As TestStruct
Dim counter_total As Integer = 0
Dim counter_good As Integer = 0
Dim counter_bad As Integer = 0
Dim list As String = ";"
Do Until objRecordSet.EOF
counter_total = counter_total + 1
Dim mail As String = ""
Dim username As String = ""
username = objRecordSet.Fields("samAccountName").Value
If Not (objRecordSet.Fields("mail").Value.GetType Is GetType(DBNull)) Then
mail = objRecordSet.Fields("mail").Value
Else
mail = ""
End If
ReDim Preserve Test(counter_total - 1)
Test(counter_total - 1).EmpID = username
Test(counter_total - 1).EmpEmail = mail
objRecordSet.MoveNext()
Loop
Return Test
End Function
End Class
Step 2.
Now we have WSDL (from step 1) to use from within ABAP, we need to turn our attention to the ABAP environment. Create a package to hold a web service
proxy. Use Transaction SE80.
Package Name: Z_TEST_WS_WEBSERVICE2
Choose to add to a transport or do locally. Your choice!
Step 3.
Create a Service Consumer (not a provider service like we do for SAP WS to be called from outside SAP).
Use Transaction: SE80 (Right Mouse on Package, Create, Enterprise Service)
Select “Service Consumer” and then “Continue”
I will use the option “external WSDL” since I will be calling a web service that is provided by a URL stored on my machine. The URL I will use is:
http://10.16.16.86/HelloWorld_WS/WebService2.asmx?WSDL
Select “Continue”
Select “URL” and Select “Continue”
Enter the URL and Select “Continue”
Enter your package name
The Prefix (ZPREFIX_WS2) is used as the prefix to the actual consumer service proxy name. You can define any unique prefix you wish.
Select “Continue” and “Complete”
At this point you have created a proxy which can be used from ABAP to call the external web service provided by the specified URL. If you refresh your package, you will see several new items.
Step 4.
Select the Client Proxy (Service Consumer) you just built and activate it.
The name of the proxy is: ZPREFIX_WS2CO_WEB_SERVICE2SOAP
Notes:
For each consumer web service you create, you will also need to create a logical port. A logical port allows the developer to specify the attributes of the web service call. For example specifying security requirements or whether the call should be synchronous or asynchronous.
Step 5.
Creating the Logical Port using Transaction SOAMANAGER
Select Tab: “Service Administration” then select “Web Service Configuration”
Search for your proxy. In my case I searched for: “ZPREFIX_WS2CO_WEB_SERVICE2SOAP”
Change the following criteria:
Search By: “Consumer Proxy”
Search Pattern: “ZPREFIX_WS2CO_WEB_SERVICE2SOAP”
Step 6.
Highlight the matched row and select “Apply Selection”. The following proxy details are displayed:
*Notice there are 0 Logical Ports (we need to create one)
Step 7.
Creating the Logical Port for our web service call.
Select the “Configurations” Tab
Select the button “Create” and the following screen is displayed:
Change the Configuration Type to “Manual Configuration”
For the Logical Port Name, type “DEFAULT”
For the Description, type “DEFAULT”
Select the check box “Logical Port is Default”
You should now have the following:
Press the button “Apply Settings”
Step 8.
Configure the Logical Port Security
The web service I am using does not require any security, go to the “Messaging Tab” and change the “Message ID Protocol” to “Suppress ID Transfer”:
Step 9.
Configure the Logical Port URL access to the Service you will be calling. This is where we will tell the Proxy which external web service we will be calling and provide the characteristics of the service.
We know the full WSDL URL of the service we wish to call is the following:
http://10.16.16.86/HelloWorld_WS/WebService2.asmx?WSDL
The computer name is: 10.16.16.86
The URL Access Path is: /HelloWorld_WS/WebService2.asmx?WSDL
Select the “Transport Settings” tab.
Enter /HelloWorld_WS/WebService2.asmx?WSDL in the URL Access Path
Enter 10.16.16.86 in the Computer Name
You should now have the following:
Select the Save button.
Step 10.
There is one last item to take care of. This step includes specifying the “SOAP Action” of the web service. You identify the SOAP Action of a web service by taking the WSDL and placing it in a web browser. In the results, you will find the SOAP Action name.
When I put my URL into a web browser:
http://10.16.16.86/HelloWorld_WS/WebService2.asmx?WSDL
In the XML results that are returned, I do a search for “soapAction”; you will see a line similar to the following:
<soap:operation soapAction="http://tempuri.org/GetMailAddress" style="document" />
As you can see, the soap action is called: http://tempuri.org/GetMailAddress
Select the Tab “Operation Specific” and enter the SOAP Action you found in the WSDL document:
***Make Sure To Uncheck the Checkboxes to the Right:
Select the Save button.
Now the fun part of actually getting to call the web service from ABAP.
Go to SE38 and create a program similar to the following:
report z_test_consumer_ws_2.
*declarations for Try/Catch block exception handling
data: exc type ref to cx_root.
data: msg type string.
start-of-selection.
* declare a reference to your proxy consumer object
data proxy_test type ref to zprefix_ws2co_web_service2soap.
try.
* instantiate the object reference
if proxy_test is not bound.
create object proxy_test type zprefix_ws2co_web_service2soap.
endif.
* declare the input and ouput references to your web service call
* you can find these by clicking on "Client Proxies" and selecting the
* #External View" tab for your proxy
data: input type zprefix_ws2get_mail_address_s1,
output type zprefix_ws2get_mail_address_so.
* there is one input value for this service call for user id
input-str_user_id = sy-uname.
* call the method (web service call) you can use the pattern to generate the code if you wish
call method proxy_test->get_mail_address
exporting
input = input
importing
output = output.
* process the output
data: wa_get_mail type zcnp_ws_phil_get_mail_1test_st.
loop at output-get_mail_address_result-test_struct into wa_get_mail.
write wa_get_mail-emp_email.
endloop.
catch cx_ai_system_fault into exc.
msg = exc->get_text( ).
write:/ msg.
endtry.
Test the program: