Skip to Content
Technical Articles

Creating a Custom SAP ME Web Service Utilizing SAP ME Public API

Run NetWeaver Developer Studio (NWDS).  Note this can also be done in plain old Eclipse with the exception that the NetWeaver server jars will need to be added as a project dependency; this will be shown when we get to that step.

NWDS

Select File -> New and find the Web / Dynamic Web Project template:

Click Next and give this Java WAR project a name.

If you’re using Eclipse instead of NWDS you likely do not have the SAP Libraries target runtime available to you.  One is available here  (http://sourceforge.net/apps/trac/sapnweclipse/) and I’ve successfully used it with the caveat that it doesn’t include the library for the security annotations, sap.com~tc~je~webservices_lib~impl.jar, which can be found in the /usr/sap/<SID>/J<xx>/j2ee/cluster/bin/ext/webservices directory in NW 7.11 CE ehp1.

Choose the default facets for this WAR project.

I left the context root the default value provided by NWDS/Eclipse.

Switch to the Java EE Perspective and your Project Explorer window should appear something like this:

Let’s create our web service by first creating a Java package for it.  Select “Java Resources: src”, right-click and select New -> Package.  I chose “com.acme.sapme.production”.

Now create the Java class for our web service.  Select the package you just created, right-click on it, choose New -> Class.  I called my class “AcmeSAPMEProductionService”.

Write your JEE 5 web service here; I’ve included my example code at the end of this blog post.  Initially you see many syntax errors because we’ve not yet included the SAP ME public API jars as dependencies of this project.

We need to add the SAP ME public API libraries as well as SAP ME’s service framework jar.  However, we don’t want them added to the WAR file itself since SAP ME will provide these libraries at run-time through NetWeaver’s classloader linking (more on this in a bit).  Right-click on the MySAPMEWebService project in the Project Explorer and choose Properties.

Select Java Build Path in the left-side pane, and then choose the Libraries tab.  Press the “Add External JARs” button and select the necessary SAP ME jars.  My example requires four: the common API, production services API, security API, and the service framework.  All these can be found within the SAP ME EAR although your versions may differ based on your release of SAP ME.

After you’ve added these libraries, the Java Build Path / Libraries setting page should look like this:

The syntax errors in your web service source should be resolved now.

Now we need to create a JEE EAR project to contain our web service WAR project.  Create the EAR project by selecting File -> New and choosing J2EE / Enterprise Application Project.

Provide the EAR project with a name.  I chose “MySAPMEWebServiceApp”:

Choose the default facets provided by NWDS/Eclipse:

Choose the MySAPMEWebService module to include it in your application EAR.

Click the “Finish” button and your Project Explorer window should resemble this:

We need to tell NetWeaver that our web service application requires SAP ME libraries.  We can do this via the NetWeaver-specific deployment descriptor, application-j2ee-engine.xml.  By creating a hard dependency on SAP ME, NetWeaver will link our web service application’s classloader with SAP ME’s classloader thereby allowing it to resolve dependencies our web service has on SAP ME’s libraries.

Open the application-j2ee-engine.xml descriptor file in EarContent/META-INF and provide the following content which will create a dependency on SAP ME allowing your web service to call SAP ME’s services.

Save this file.  Right-click on the MySAPMEWebServiceApp project in the Project Explorer and choose Export -> SAP EAR.

NWDS/Eclipse will automatically build the MySAPMEWebService WAR project and build the MySAPMEWebServiceApp EAR.  If you chose to write the EAR to the project workspace it will appear in the Project Explorer window:

In NWDS, you can right-click on the MySAPMEWebServiceApp.ear file and select Deploy.  In plain Eclipse you’ll have to deploy via telnet or JSPM.  Since this is my first deployment, I have to log into NetWeaver:

To verify the web service is deployed and to find the exact URL to the WSDL, open NetWeaver Administrator and open Single Service Administration.  Select the Service Definition tab, the Browse sub-tab, and then choose the “SoftwareComponents” classification in the combo box.  Look for “com.sap/MySAPMEWebServiceApp”.

Expand the “com.sap/MySAPMEWebServiceApp” element until you see the AcmeChangeProductionService service definition.  Select it and in the lower pane, choose the WSDL tab.

Clicking on the WSDL URL should open it in Internet Explorer.

Strip off the “&mode=ws_policy” parameter from the URL and you’ll get the full WSDL:

Fire up soapUI  (http://www.soapui.org/) and create a new project.  Specify our WSDL above as the initial WSDL:

Click “OK” and the project will appear in the Project window of soapUI.

Right-click on AcmeChangeProductionServiceBinding and select “Show Interface Viewer”.  Select the Service Endpoints tab and enter the Username and Password of the UME user authorized to run this web service.  SAP ME installation typically requires you to create a technical user called “MESYS”.

This user will be authenticated via HTTP Basic Authentication by NetWeaver.  Close the Interface Viewer and open Request 1 under the “changeProduction” operation.

Note that this request will only work if your SAP ME master and production information is correctly set up.  In this test case I have two shop orders, 20100823-01 and 20100823-02.  The first order has hundreds of SFCs released on it.  I’m going to move two of those SFCs, PCB-1-0043 and PCB-1-0044 from shop order 20100823-01 to shop order 20100823-02 and adjust the build quantities of both orders. Clicking the green arrow in the upper-left corner of the Request 1 window will send the request to SAP ME.

I’ve received a successful response from SAP ME showing that these two SFCs have been moved to shop order 20100823-02.

That’s it.  If you have additional questions, please post them to the “Manufacturing Execution” forum which I monitor for integration/web service related questions for SAP ME.

————

Below is the code used in this example:

package com.acme.sapme.production;

import javax.annotation.Resource;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;

import com.sap.engine.services.webservices.espbase.configuration.ann.dt.AuthenticationDT;
import com.sap.engine.services.webservices.espbase.configuration.ann.dt.AuthenticationEnumsAuthenticationLevel;
import com.sap.engine.services.webservices.espbase.configuration.ann.rt.AuthenticationRT;
import com.sap.me.frame.domain.BusinessException;
import com.sap.me.frame.domain.InvalidInputException;
import com.sap.me.production.ChangeProductionRequest;
import com.sap.me.production.ChangeProductionResponse;
import com.sap.me.production.ChangeProductionServiceInterface;
import com.sap.me.security.RunAsServiceLocator;
import com.visiprise.frame.configuration.ServiceReference;

@WebService(name = "AcmeChangeProductionService", targetNamespace = "com:acme:sapme:production")
@AuthenticationDT(authenticationLevel = AuthenticationEnumsAuthenticationLevel.BASIC)
@AuthenticationRT(AuthenticationMethod = "sapsp:HTTPBasic")
public class AcmeSAPMEProductionService
{
    @Resource
    private WebServiceContext wsContext;

    @WebMethod
    @WebResult(name = "Response", targetNamespace = "com:acme:sapme:production")
    public ChangeProductionResponse changeProduction(
        @WebParam(name = "Site", targetNamespace = "com:acme:sapme:production")
        String site,
        @WebParam(name = "Request", targetNamespace = "com:acme:sapme:production")
        ChangeProductionRequest Request)
        throws BusinessException
    {
         String user = wsContext.getUserPrincipal().getName();         
        if ((null == site)||"".equals(site)) {
            throw new InvalidInputException("no site defined in request message", "site", site);
        }
        // lookup service
        ServiceReference serviceRef = new ServiceReference("com.sap.me.production", "ChangeProductionService");
        RunAsServiceLocator serviceLocator = new RunAsServiceLocator(user, site, null);
        ChangeProductionServiceInterface service = serviceLocator.getService(serviceRef, ChangeProductionServiceInterface.class);
       
        // run service
        ChangeProductionResponse serviceResponse = service.changeProduction(Request);
        return serviceResponse;
    }
}
7 Comments
You must be Logged on to comment or reply to a post.
  • Tim,

    This really looks simple and interesting, I am gonna try it on Monday.. Thanks for sharing such great methode to create web services out of Public API..

    Am I right “Supported API” = Public API??

    • The SAP ME Public API (which we refer to internally as “PAPI”) is the supported API.  Bear in mind, you can write your own web service annotated class, pass in whatever you want, then call anything in SAP ME. Naturally, you should only call public (i.e. supported) APIs or else you take the chance of your web service not working after an upgrade.
  • Hi Tim,

    As per the document I have created WS using ME 6.0 public APIs and now I am testing from WS Navigator and getting the error like

    Web service returned error. Fault Code: “(http://schemas.xmlsoap.org/soap/envelope/)Client” Fault String: “Supplied userRef is not a valid UserBOHandle”

    I have used admin to execute the WS from WS Navigator.

    I have also checked the NW log and got the below details. Could you please help me to solve the issue.

    Error details:

    “Deprecated scope of type SERVERSESSION_AT_LEAST_ONE_APP_SCOPE is used! Please replace the usage of scopes with new mechanism based on “Cross application session communication API”.”

    Used API Library

    me.common.api-6.0.4.2.jar

    me.production.api-6.0.4.2.jar

    me.security.api-6.0.4.2.jar

    service-core-1.1.1-SNAPSHOT.jar

    Thanks

    Chandan

    • I have no idea what the error “Deprecated scope of type…” means, but I can help you with the UserBOHandle issue. 

      Can you show me your request that caused this error?  Maybe provide a screenshot of the WS Navigator?

      • Hi Tim,

        I have used the same code which you have provided in your blog. I am only passing site and sfc in request structure and after clicking the event I am getting that error. Could you please provide your suggestion here.

        Thanks

        Chandan