Wednesday, January 9, 2013

Direct SOAP communication between SAP and external systems using client proxies

This is probably the most technical blog I have written so far.
A few weeks ago I accepted the challenge to set up a realtime SOAP interface between SAP CRM and an external application. Connecting to this (Google) application has several challenges.
  1. It consists of about 20 webservices
  2. The authentication procedure is OAuth2.0
  3. The documentation clearly states that it is not recommended to build your own interface from scratch, but to always use the delivered client libraries (available in Java, Python, PHP, .NET and Ruby).
  4. The API is not widely implemented yet.
So, enough ingredients for a good struggle. So, let’s see what happened…

Today's blog contains the first step of the chain, importing the WSDL's of the webservices into SAP CRM, generating client proxies. In the next few weeks, you can expect more information on how to use the client proxies in ABAP, how to debug and analyse the SOAP messaging, and maybe even something about OAUTH2.0 in ABAP.


Creating Client Proxies from WSDL Files

After asking around, I found out that there is something available in SAP Netweaver called a ‘client proxy’. According to the rumours, this would totally fit the job. What it basically does is read a WSDL file and generate ABAP classes that represent the webservices functionality in ABAP, and generate SOAP messages in the specified format.
As an example, let’s say we have an orderservice.
In the orderservice wsdl, the data types and service methods are described. For instance data type ORDER (a large structure containing all kinds of fields) and a method called ‘CreateOrder’.
When importing the orderservice wsdl as a clientproxy into SAP, a class will be created called Zorderservice (if this is what I enter in the wizard) with a method called ‘Z_Create_Order’. Also, a data structure called z_order will be created. All automatically generated from the WSDL.
Let me throw in some screenshots to make it more clear:
SE80 -> Edit Object
 Tab ‘Enterprise Services’ -> Tick option ‘Client Proxy’ -> Click New.
Select URL/HTTP Destination, and enter the location of the WSDL. The WSDL will be downloaded in the process, and used to create the objects.
In this step, I encountered the first problem. Even though this is how it is supposed to be done, the SAP system kept telling me that an “Exception occurred in the HTTP Framework, 500Native SSL error”. So, my first guess was that there was something wrong with the SAP system, or with the WSDL or with the ICF Node responsible for the download.
Eventually I actually didn’t find out what the real problem was, but I am guessing the SAP server was not able to download the WSDL all by himself, so I had to help him a little. I downloaded the WSDL (which apparently is actually a pretty readable XML file), and imported it manually into SAP.
Click continue -> continue and enter packages, prefixes and transport requests as you go.
Click on ‘Complete’ when you get to the last screen and pray… Keep praying for a few minutes (depending on the size of the webservice of course).
When you’re done, you will find yourself in the properties tab of the client proxy.
Next to the properties tab, you will find the Name Problems, describing that some of the names have been shortened because SAP does not allow class names and data type names longer than 30 characters. You might also run in to a data type already exisiting with that name. These possible name problems have been fixed automatically, and the tab now shows the new names.
Next tab is the External View. The External view shows a hierarchical overview of all the methods available to the service. When clicking on the nodes, you will see the details of the related ABAP class or ABAP methods or ABAP data type, depending on what kind of node you clicked. The external view shows the data as if you are trying to understand the contents of the WSDL.
Next tab is the Internal view. This basically gives you the same information, but the other way round. It shows the hierarchical tree from the ABAP side, so you will see the ABAP class, methods and data types, and can check the details by selecting the different nodes.
Next tab is the ‘Used Objects’ tab. This shows a list of all objects that have been generated by the wizard. Note the second column from the right. This is the status, and might be important. If the status is green (active), all is well. If the status is a pencil, it means it has been revised. For instance, the name has been adjusted due to name problems (as we saw in the name problems tab). If an object is in warning, or error or inactive, you should check the warnings tab (last one in the list). There might be unsolved issues you need to solve manually.

The next tab is the configuration. Here you can adjust some of the features of the client proxy, which will influence it’s behaviour. I have not had to change these values, so to be honest, I haven’t really paid much attention to them.
The last (but not least) tab is the Warnings tab. You will probably find that there are quite some warnings. Not all need your attention. For instance, the warning ‘The XSD type double does not exactly correspond to the ABAP type FLTP’ could be a problem, but does not necessarily have to be one. After all, type FLTP is the closest that can get to the XSD type ‘double’. The problem is that when programming the ABAP, the syntax check will have less constraints on what you pass to the field, so you have more risk running into problems at runtime.
Note by the way the questionmark column… . Doubleclicking the questionmark actually gives you very detailed information on the warnings. Well done SAP!
Other warnings do need your attention though. Especially the ‘Item is part of recursion (see long text for additional information)’. Unfortunately, the table type at hand contains an attribute referencing itself. As an example, a table of orders could contain an attribute of type ordertable, referencing for instance a set of suborders. ABAP tabletypes do not understand this, so the warning is raised. This warning does need your attention, because it needs to be fixed before you can properly activate the client proxy. The way to fix this is to set the attribute ‘Untyped Mapping’ in the detail screen of the structure in either the external or internal view tab.
There is one very big discomfort in this though, ‘Untyped Mapping’ means that the attribute (the order in our example) will be registered as XSDANY in the abap dictionary. This basically demotes the attribute to an xstring, which does not make the programming easier, because you will have to create the structure that goes in there manually and convert it to a proper XML.
There is a way out though.
When coding your program that calls the interface, use the following code to create the xstring from the structure:
DATA: lr_xml_factory TYPE REF TO if_proxy_sxml_stream,
ls_xstring TYPE xsdany.
lr_xml_factory = cl_proxy_sxml_factory=>create_sxml_stream( ).
CALL METHOD lr_xml_factory->abap_to_xml( name = 'root' abap_data = <your structure> ).
ls_xstring = lr_xml_factory->get_output( ).
ls_xstring will contain the data in XML format, exactly as specified by the structure. Append this xstring to the table (of type xsdany).

In the next few weeks, you can expect more information on how to use the client proxies in ABAP, how to debug and analyse the SOAP messaging, and maybe even something about OAUTH2.0 in ABAP.