Introduction
In this BSP Developer's Journal, I will look at a subject that isn't really directly BSP
related: WebServices developed in ABAP. Although the WebService technology isn't technically
part of BSP, it is an import aspect of the infrastructure that we have created to support our
BSP development. Our standalone WebAS has allowed us to extend our 46C R/3 by exposing
functionality via WebServices. Also for the first time in one of my developer's journals, I
will discuss how our upcoming NetWeaver 04 upgrade will impact and extend the functionality
that we already have.
Shop Floor Interfaces
6 months ago, our IT department was faced with a new challenge. We had been asked to build
several interfaces from our Global R/3 system to our localized Shop Floor systems. Each of our
facilities around the world (North America, Europe, and Asia) have on site systems (MSSQL
written in Visual Basic) that capture data directly from the production lines. Our goal was to
take this information that was being captured by these shop floor systems and feed it back to
our R/3 system in near real time (no more than 10 or 15 minutes lag time). The data we would be
sending would be QM defect information, production counts, and assembly/sub-assembly backflushes
and scraps. The challenge came from the fact that we would need robust interfaces that would
operate 24x7 on a global scale across a sometimes tenuous wide area network. To complicate
matters, many of the shop floor systems were localized to run in the native language and code
page of their respective areas. Also our support staff is our development staff - currently
only 4 people. We therefore needed a solution that wouldn't require 24x7 babysitting.
Traditionally we would have looked to external interface tools to bridge this gap. Our
development group's expertise lies within the Microsoft tools arena, so we have used the DCom
connector or the new .Net Connector in the past. Although both good tools, we were really
concerned about inserting another failure point into this solution. We were ready to try out
something new. Since our WebAS landscape was already highly available and well supported, it
made since to try and leverage it for this solution as well. We had experimented with the
WebService technology in 620 before and it certainly seemed simple enough to give it a try.
Also because of its very design, WebServices took care of several of our problems. HTTP(s) is
obviously well suited to network transmission over a wide area network. Ultimately using HTTPS
did give us a measure of security as well. Finally WebServices easily supports Unicode. This
made bridging the gap between the code pages of our localized shop floor systems and our MDMP
SAP solutions a breeze.
First up you will want to make sure that your Service Nodes are active. Everything that we
will be interested in is under sap/bc. These are the nodes that exposed the documentation and
WSDL definitions for your webservices, in addition to being the interface for calling them as
well. All of your webservices are exposed under a single service node (unlike in 640, where
each generated webservice has its own node). This does reduced your configuration options.
!https://weblogs.sdn.sap.com/weblogs/images/1918/ws_sicf.jpg|height=74|alt=image|width=376|src=https:...!
Next up we will need to create an RFC in our WebAS to be exposed as a webservice. In a 620
system with an active SOAP service, all RFCs are automatically exposed as webservices. This is
where having a standalone WebAS came in quite handy. Because our R/3 system, which houses the
RFCs that would expose our business logic, must be bridged by creating proxy RFCs in our
standalone WebAS, we retain a measure of control over what is exposed to the outside. This also
allows us to simplify the interface to the WebServices or to combine multiple R/3 RFCs into a
single WebService call. Many of these "problems" with WebServices in 620 have been corrected in
640 - I will show this later in the weblog. For this weblog, let's look at very simple example
that is a small part of total solution. In this example we will expose a WebService that shows
the listing of Plants that we have setup in our system along with a description of each plant.
Function Interface
function z_e_rfc_ws_get_plant_values.
*"----
""Local interface:
*" EXPORTING
*" VALUE(MSG_TEXT) TYPE MSG
*" VALUE(SUBRC) TYPE SYSUBRC
*" VALUE(SHSVALTAB) TYPE SHSVALTAB
*"----
The interface of our proxy RFC has no input parameters. Rather than throwing exceptions, as
you normally would in ABAP, we decided to handle errors by returning a SUBRC (Return Code) and
MSG_TEXT (string with the description of the error). This should make the handling of errors a
little clearer on the calling side and gives us better control over error situations. Finally
in this example we will return the Plant/Plant Description in the structure SHSVALTAB. This
structure has a simple KEY and VALUE components and is commonly used in BSP programming (no
reason to reinvent the wheel).
Don't forget to mark your RFC as remotely callable:
The Coding
In the following coding you can see that all we are doing is exposing an SAP BAPI to the outside
world. However we have greatly simplified the interface to this BAPI by making it specific to
our situation. That way the programmers on the calling side really don't have to understand
anything about the SAP system. They just need to know that they want a plant code and
description. You can also see that we dynamically look up our RFC destination from a
configuration table. This gives us greater flexibility, especially when testing between Dev and
QAS systems.
function z_e_rfc_ws_get_plant_values.
*"----
""Local interface:
*" EXPORTING
*" VALUE(MSG_TEXT) TYPE MSG
*" VALUE(SUBRC) TYPE SYSUBRC
*" VALUE(SHSVALTAB) TYPE SHSVALTAB
*"----
constants: rfc_name type rs38l_fnam
value 'Z_E_RFC_WS_GET_PLANT_VALUES'.
data: rfcdest type rfcdest.
****Read the RFC Destination from the configuration Table
select single rfcdest from zes_rfc_dest
into rfcdest
where name = rfc_name.
field-symbols: