<sap:connector name="SapConnector" jcoClient="100" jcoUser="User"
jcoPasswd="Password" jcoLang="en" jcoAsHost="host" jcoSysnr="00"
jcoTrace="true" jcoPoolCapacity="3" jcoPeakLimit="10"/>
MuleSoft Enterprise Java Connector for SAP
Mule Runtime Engine versions 3.5, 3.6, and 3.7 reached End of Life on or before January 25, 2020. For more information, contact your Customer Success Manager to determine how you can migrate to the latest Mule version. |
Premium
This connector requires a separate license. Please contact [MuleSoft] if you want to evaluate or use this connector. |
Introduction
The Mule SAP Transport uses SAP Java Connector (JCo) libraries, thus enabling your Mule application to:
-
Execute a BAPI function over sRFC (synchronous RFC), tRFC (transactional RFC), and qRFC (queued RFC).
-
Act as a JCo server to be called as a BAPI over sRFC, tRFC, and qRFC.
-
Send IDocs over tRFC and qRFC.
-
Receive IDocs over tRFC and qRFC
-
Transform all SAP objects (JCoFunction & IDocs) to/from XML.
There are four versions of the MuleSoft Enterprise Java Connector for SAP:
Stateful transactions, involving multiple outbound endpoints, only work starting in Mule 3.3 with the transactional scope. |
Installation
The SAP transport needs JCo libraries to operate. The following section explains how to setup MULE ESB so that you can use the SAP transport in your Mule application.
This procedure assumes that you already have a Mule instance installed on your host machine. If not, follow the instructions for [downloading and installing Mule].
Throughout this document, we use $MULE_HOME to refer to the directory where Mule is installed.
|
-
Download the SAP JCo and IDOC libraries from the SAP site: http://service.sap.com/connectors (To do this, you need SAP User ID).
-
Make sure that the SAP jars available to your Mule application and/or Mule ESB instance. JCo relies on native library, which requires additional installation steps.
-
If you plan to use SAP as an Inbound Endpoint (i.e., Mule will be called as a BAPI or will receive IDocs), you must perform additional configuration within the service file at the OS level.
About the SAP JCo and IDoc Library Versions The SAP Transport requires the following files:
Every SAP customer/partner has access to the [SAP Service Market Place (SMP)]. Here, you can download both these files as well as the NetWeaver RFC Library and other connectors. The SAP JCo libraries are OS-dependent, so make sure to download the SAP libraries that correspond to the OS and hardware architecture of the host server on which Mule will be running. |
Making Jars Available to Your Mule ESB Application
Following the instructions provided by SAP to install the JCo libraries, but remember that certain jar files must be located in your application CLASSPATH, and the dynamic link library 9(dll/so) must reside in you LD_LIBARY_PATH.
Next, include the transport jar file (mule-transport-sap-{version}.jar
) in your application CLASSPATH.
The Mule SAP Transport depends on three libraries:
-
mule-transport-sap-{version}.jar
-
sapjco-3.0.x.jar
-
sapidoc-3.0.x.jar
You need to place these three files in the same directory. |
How to place Jars in common directory shared among apps If you’re going to deploy multiple applications to the same server, it makes sense to keep all of these Jars in a single folder rather than having them repeated for each app. Mule does not support this out of the box, but there’s a work around for that. For the SAP connector, MuleSoft recommends the following directories:
By placing the libraries in these directories, you will share them among all applications running within the same Mule ESB instance. As SAP JCo configuration is a singleton, if you go this way, then all your applications will share the same configuration, including the JCo destination repository. |
For this setup to work, you must also manually configure the What you did so far is enough to run this in a Mule ESB Standalone instance, however to make this run properly in the Anypoint Studio runtime and be able to test your app while developing it, you must do the following:
|
About the Application CLASSPATH Your application library directory is automatically enabled to support dynamic libraries. IF you are not including these there then you also need to tell Mule ESB where the SAP JCo dynamic linked library resides. To accomplish this, you can do either of the following:
IMPORTANT: Do not combine both strategies (For example putting JCo libraries in the mule instance shared library directory (e.g., == Example: Shipping All Dependencies Inside Your Application Let’s assume you have an application called sap-test deployed in
== SAP Inbound Endpoint Requirements If you want to receive IDocs or be called as a BAPI (JCo Server) and you don’t want to use the PORT number as the value for
In the above file, you must add your gateway (which is configured through the For example, set the following,
Port 3300 is predefined by the SAP, so if you need to validate other port numbers based on your SAP instance number. == Namespace and Syntax === XML namespace: [ === Connector Syntax === Endpoint Syntax ==== Inbound Endpoint
==== Outbound Endpoint
== The Connector The [sap:connector] element allows the configuration of JCo connection parameters that can then be shared among [sap:inbound-endpoints] and [sap:outbound-endpoints] in the same application. == Configurable Attributes
=== Configuration Attribute
== SAP Solution Manager The MuleSoft Enterprise Java Connector for SAP is [SAP Solution Manager] ready. This means that the connector complies with the minimum requirements to register in the SAP System Landscape Directory. To configure it, you create a child element
=== Example
|
If you have multiple SAP connectors in the same Mule application or even on the same Mule server, then there is no reason to configure a different SLD for every one of them.
Unless you need to register with different SLD servers, you can configure a single sap:sld-config
for only one sap:connector
, and that SLD will serve for all SAP connectors running on the same host.
== Endpoints
The MuleSoft Enterprise Java Connector for SAP supports both [inbound] and [outbound] endpoints.
-
[Inbound-Endpoint]: Receives IDocs and BAPI calls over RFC.
-
[Receiving IDocs]
-
[Receiving BAPI calls]
-
-
[Outbound Endpoint]: Sends IDocs and executes BAPIs over RFC.
=== Endpoint Address
To support for dynamic endpoints, the SAP Transport supports a URI-style address, for which the general format is:
address="sap://jcoUser:jcoPasswd@jcoAsHost?attr1=value1&attr2=value2& … &attrN=valueN"`
These attributes can be:
-
The same attributes supported in the connector or endpoint element (for example jcoClient, jcoSysnr, etc.)
-
Specific SAP Connection Properties (for example jco.client.r3name, jco.client.type, etc.)
Whenever attributes that are not specified, default values are used.
You can usea [Mule expressions] inside the address attribute, just as you do for other Mule ESB transports. |
Example of an Inbound Endpoint:
<sap:inbound-endpoint
address="sap://TEST_USER:secret@localhost?type=function&rfcType=trfc&jcoClient=100&jcoSysnr=00&jcoPoolCapacity=10&jcoPeakLimit=10&jcoGwHost=localhost&jcoGwService=gw-service&jcoProgramId=program_id&jcoConnectionCount=2"/>
Example of an Outbound Endpoint Address:
<sap:outbound-endpoint
address="sap://TEST_USER:secret@localhost?type=function&rfcType=trfc&jcoClient=100&jcoSysnr=00&jcoPoolCapacity=10&jcoPeakLimit=10"/>
You must "escape" the ampersand sign (''&'') in the address attribute, replacing it with ''&';' |
== Prioritizing Connection Properties
Properties for SAP JCo connections (inbound and outbound) can be configured in numerous places. The following list details the priorities accorded to values specified in different places, with the highest priority level listed first.
-
Attributes at
<sap:inbound-endpoint/>
and<sap:outbound-endpoint/>
level (For example jcoClient, jcoUser, jcoPasswd, jcoSysnr, jcoGwHost, jcoProgramId) -
Properties in the address attribute at
<sap:inbound-endpoint/>
and<sap:outbound-endpoint/>
level -
Properties inside the Map configured in the
jcoClientExtendedProperties-ref
and/orjcoServerExtendedProperties-ref
attributes at at<sap:inbound-endpoint/>
and<sap:outbound-endpoint/>
level -
Attributes configured at
<sap:connector/>
level (For example jcoClient, jcoUser, jcoPasswd, jcoSysnr) -
Properties inside the Map configured in the
jcoClientExtendedProperties-ref
at<sap:connector/>
level -
Default values
== XML Definition
This definition is the XML representation of a function (JCOFunction) or IDoc (IDocDocument / IDocDocumentList). In short, these are the XML documents you will be receiving from and sending to SAP.
The SAP transport includes [transformers] that will convert the XML documents exchanged between the endpoints and SAP into corresponding SAP objects that the endpoints can handle.
The complete documentation for the different XML documents can be found [here]:
-
[JCo Function]
-
[Version 1]
-
[Version 2]
-
-
[IDoc]
== Inbound Endpoint
The SAP inbound endpoint acts as an RFC server or IDoc server. The JCo server needs to register against the SAP instance, and for this reason it requires both client and server configuration attributes.
Attribute | Description | Default Value | Since Version |
---|---|---|---|
address |
The standard way to provide endpoint properties. For more information see [Endpoint Address]. |
1.0 |
|
exchange-pattern |
The available options are request-response and one-way. |
1.0 |
|
functionName |
If the type is function then this is the name of the BAPI function that will be handled. If no value is provided, then a generic handler is configured to receive all calls |
1.0 |
|
jcoAsHost |
The SAP application server host. (Use either the IP address or server name). |
1.0 |
|
jcoClient |
The SAP client. This is usually a number (i.e., 100). |
1.0 |
|
jcoClientExtendedProperties-ref |
A Reference to |
1.0 |
|
jcoConnectionCount |
The number of connections that should be registered at the gateway. |
2 |
1.0 |
jcoGwHost |
The gateway host on which the server should be registered. |
1.0 |
|
jcoGwService |
The gateway service, i.e. the port on which registration is performed. |
1.0 |
|
jcoLang |
The login language. If not defined, the default user language is used. |
en |
1.0 |
jcoPasswd |
The password associated with the user for password-based authentication. |
1.0 |
|
jcoPeakLimit |
The maximum number of simultaneously active connections that can be created for a destination. |
10 |
1.0 |
jcoPoolCapacity |
The maximum number of idle connections kept open by the destination. No connection pooling takes place when the value is 0. |
5 |
1.0 |
jcoProgramId |
The program ID with which the registration is performed. |
1.0 |
|
jcoServerExtendedProperties-ref |
A Reference to |
1.0 |
|
jcoSysnr |
The SAP system number. |
1.0 |
|
jcoUser |
The user for password-based authentication. |
1.0 |
|
name |
The reference name of the endpoint used internally by Mule configuration. |
1.0 |
|
outputXml |
Whether the endpoint should set as payload the XML representation (String) of the SAP Object (Function or IDoc) or the SapObject wrapper itself. Setting this flag to 'true' removes the need for the object-to-xml transformer. |
false |
2.2.2 |
rfcType |
The type of RFC the endpoint used to receive a function or IDoc. The available options are srfc (which is sync with no TID handler), trfc and qrfc (both of which are async, with a TID handler). |
srfc |
1.0 |
type |
The type of SAP object this endpoint will process (i.e., function, idoc) |
function |
1.0 |
xmlVersion |
The version of the output/input XML. IDocs only support Version 1, while for functions you have Version 1 (default) and Version 2 (DataMapper friendly) |
1 |
2.2.2 |
=== Example
<sap:inbound-endpoint exchange-pattern="request-response" type="function" rfcType="srfc"
jcoGwHost="gateway-host" jcoGwService="gateway-service" jcoProgramId="program_id"
jcoConnectionCount="2" functionName="BAPI_FUNCTION_NAME" jcoServerExtendedProperties-ref="mapWithServerProperties"/>
== Output Mule Message
The inbound endpoint generates a Mule Message with the following payload contents:
-
A
org.mule.transport.sap.SapObject
instance. This is Java POJO whose two main properties are:-
type:
SapType.FUNCTION
orSapTYPE.IDOC
depending on whether a BAPI call or an IDoc is being received. -
value: The type depends on the specific JCo object
com.sap.conn.idoc.IdocDOCUMENT
orcom.sap.conn.idoc.IDocDOCUMENTLIST
for IDocs andcom.sap.conn.jco.JCoFunction
for BAPI calls.
-
-
A string with the XML document when outputXML is true.
The payload can be transformed into an [XML string] with the <sap:object-to-xml/>
transformer.
== Receiving IDocs
To configure a IDoc Server, you need to complete the following steps:
-
Set the
type
parameter to idoc. -
Define the
rfcType
parameter as trfc or qrfc (IDocs are asychronous by definition, so they cannot be received srfc). -
[Configure a TID handler]. (The default is an in-memory TID handler).
-
Specify the following required attributes: jcoGwHost, jcoGwService, jcoProgramId.
-
Specify required connection attributes, as necessary, for the endpoint or the connector. This might include, for example, jcoClient, jcoUser, jcoPasswd, jcoAsHost, jcoSysnr.
=== A Sample IDoc Server Configuration
<mule>
...
<sap:connector name="SapConnector" jcoClient="100" jcoUser="mule_user" jcoPasswd="secret" jcoLang="en"
jcoAsHost="sap-as.mulesoft.com" jcoSysnr="00" jcoTrace="true" jcoPoolCapacity = "3" jcoPeakLimit="10"
jcoClientExtendedProperties-ref="sapProperties"/>
...
<flow name="sapExample">
<sap:inbound-endpoint name="sapInbound" exchange-pattern="request-response" type="idoc"
rfcType="trfc" jcoGwHost="sapgw.mulesoft.com" jcoProgramId="idoc_send" jcoGwService="sapgw00"
jcoConnectionCount="2" jcoClientExtendedProperties-ref="sapProperties">
<sap:default-in-memory-tid-store/>
</sap:inbound-endpoint>
...
</flow>
</mule>
== Receiving BAPI Calls
To configure a BAPI RFC Server you must complete the following steps:
-
Set the
type
parameter to function. -
Define the
rfcType
parameter to trfc, qrfc, or srfc. (IfrfcType
is not specified, srfc is used by default.) -
If
rfcType
is trfc or qrfc, then you may also need to [configure a TID handler]. -
Specify the following required attributes: jcoGwHost, jcoGwService, jcoProgramId.
-
Specify the required connection attributes, as necessary, for the endpoint or the connector. This might include, for example, jcoClient, jcoUser, jcoPasswd, jcoAsHost, jcoSysnr.
== Returning to SAP
After the flow executes and if the SAP inbound endpoint is request-response, then Mule will return values to the calling SAP instance. Return values can be represented with the XML representation of the [Jco Function]. There are three possible scenario:
-
Normal Execution: Just populate values in the export, changing, or tables sections.
-
Exception: Populate an exception in the exceptions section. This will throw an
AbapException
that will be treated by SAP as an application error. -
Flow Exception: An exception thrown by the flow will be treated in SAP as a system failure
(SYSTEM_FAILURE)
.
=== A Sample BAPI RFC Server Configuration
<mule>
...
<sap:connector name="SapConnector" jcoClient="100" jcoUser="mule_test" jcoPasswd="secret" jcoLang="en" jcoAsHost="sapas.mulesoft.com"
jcoSysnr="00" jcoTrace="true" jcoPoolCapacity = "3" jcoPeakLimit="10" jcoClientExtendedProperties-ref="sapProperties"/>
...
<flow name="sapExample">
<sap:inbound-endpoint name="sapInbound" exchange-pattern="request-response" type="function" rfcType="trfc" jcoGwHost="sapas.mulesoft.com"
jcoProgramId="rfc_send" jcoGwService="sapgw00" jcoConnectionCount="2"/>
...
</flow>
</mule>
== Configuring the TID Handler
The TID (Transaction ID) handler, an important component for tRFC and qRFC, ensures that Mule ESB does not process the same transaction twice.
The SAP connector allows you to configure different TID stores:
-
In Memory TID Store: This default TID store facilitates the sharing of TID within the same Mule ESB instance. If the
rfcType
is tRFC or qRFC, and no TID store is configured, then this default store is used. This is not recommended for production environment and this option doesn’t work in a clustered environment. -
Mule Object Store TID Store: This wrapper uses existing Mule ESB object stores to store and share TIDs. If you need multiple MUle ESB server instances, you should configure a JDBC Object Store or a cluster-enabled Object Store so that you can share TIDS among the instances.
If the rfcType is configured to sRFC, or is not provided (thus defaulting to sRFC), then no TID handler is configured. Furthermore, if a TID handler has been configured in the XML file, it will be ignored.
|
=== Example of a Default In-memory TID Store
To configure an in-memory TID Store successfully, you must understand the following:
-
The in-memory TID Store won’t work as expected if you have multiple Mule ESB instances that share the same program id.
-
The
rfcType
in the<sap:inbound-endpoint…/>
should be tRFC or qRFC. -
Configuring the child element
<sap:default-in-memory-tid-store/>
is optional, since the in-memory handler is the option by default.
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:sap="http://www.mulesoft.org/schema/mule/sap"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/sap http://www.mulesoft.org/schema/mule/sap/current/mule-sap.xsd
http://www.mulesoft.org/schema/mule/xml http://www.mulesoft.org/schema/mule/xml/current/mule-xml.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd">
<!-- Configuration for both SAP & the TID Store -->
<spring:bean id="sapProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
<spring:property name="ignoreUnresolvablePlaceholders" value="true" />
<spring:property name="location" value="classpath:sap.properties"/>
</spring:bean>
<!-- SAP Connector -->
<sap:connector name="SapConnector" jcoClient="${sap.jcoClient}"
jcoUser="${sap.jcoUser}" jcoPasswd="${sap.jcoPasswd}" jcoLang="${sap.jcoLang}" jcoAsHost="${sap.jcoAsHost}"
jcoSysnr="${sap.jcoSysnr}" jcoTrace="${sap.jcoTrace}" jcoPoolCapacity="${sap.jcoPoolCapacity}" jcoPeakLimit="${sap.jcoPeakLimit}"/>
<flow name="idocServerFlow">
<sap:inbound-endpoint name="idocServer" exchange-pattern="request-response" type="idoc" rfcType="trfc" jcoGwHost="${sap.jcoGwHost}"
jcoProgramId="${sap.jcoProgramId}" jcoGwService="${sap.jcoGwService}" jcoConnectionCount="${sap.jcoConnectionCount}">
<sap:default-in-memory-tid-store/>
</sap:inbound-endpoint>
...
</flow>
</mule>
=== A Sample JDBC-based Mule Object Store TID Store
To configure the Mule Object Store TID Store, complete the following steps:
-
Configure the
rfcType
in the<sap:inbound-endpoint…/>
component as tRFC or qRFC. -
Configure the child element
<sap:mule-object-store-tid-store>
. -
Configure a DataSource bean with Database Connection details.
-
Configure JDBC connector.
The child element of <sap:mule-object-store-tid-store> can be any of the supported Mule Objet Stores.
|
This example illustrates how to configure MySQL-based JDBC object store.
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:sap="http://www.mulesoft.org/schema/mule/sap"
xmlns:jdbc="http://www.mulesoft.org/schema/mule/jdbc"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/sap http://www.mulesoft.org/schema/mule/sap/current/mule-sap.xsd
http://www.mulesoft.org/schema/mule/jdbc http://www.mulesoft.org/schema/mule/jdbc/current/mule-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd">
<!-- Configuration for both SAP & TID Store -->
<spring:bean id="sapProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
<spring:property name="ignoreUnresolvablePlaceholders" value="true" />
<spring:property name="location" value="classpath:sap.properties"/>
</spring:bean>
<spring:bean id="jdbcProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<spring:property name="location" value="classpath:jdbc.properties"/>
</spring:bean>
<!-- TID Store configuration -->
<spring:bean id="jdbcDataSource"
class="org.enhydra.jdbc.standard.StandardDataSource"
destroy-method="shutdown">
<spring:property name="driverName" value="${database.driver}"/>
<spring:property name="url" value="${database.connection}"/>
</spring:bean>
<jdbc:connector name="jdbcConnector" dataSource-ref="jdbcDataSource" queryTimeout="${database.query_timeout}">
<jdbc:query key="insertTID" value="insert into saptids (tid, context) values (?, ?)"/>
<jdbc:query key="selectTID" value="select tid, context from saptids where tid=?"/>
<jdbc:query key="deleteTID" value="delete from saptids where tid=?"/>
</jdbc:connector>
<!-- SAP Connector -->
<sap:connector name="SapConnector" jcoClient="${sap.jcoClient}"
jcoUser="${sap.jcoUser}" jcoPasswd="${sap.jcoPasswd}" jcoLang="${sap.jcoLang}" jcoAsHost="${sap.jcoAsHost}"
jcoSysnr="${sap.jcoSysnr}" jcoTrace="${sap.jcoTrace}" jcoPoolCapacity="${sap.jcoPoolCapacity}" jcoPeakLimit="${sap.jcoPeakLimit}"/>
<flow name="idocServerFlow">
<sap:inbound-endpoint name="idocServer" exchange-pattern="request-response" type="idoc" rfcType="trfc" jcoGwHost="${sap.jcoGwHost}"
jcoProgramId="${sap.jcoProgramId}" jcoGwService="${sap.jcoGwService}" jcoConnectionCount="${sap.jcoConnectionCount}">
<sap:mule-object-store-tid-store>
<jdbc:object-store name="jdbcObjectStore" jdbcConnector-ref="jdbcConnector"
insertQueryKey="insertTID"
selectQueryKey="selectTID"
deleteQueryKey="deleteTID"/>
</sap:mule-object-store-tid-store>
</sap:inbound-endpoint>
...
</flow>
</mule>
Make sure to note the following points:
-
Specific configuration attributes are store in two properties files:
sap.properties
andjdbc.properties
. -
To configure more than one PropertyPlaceholder, the first one must have the property ignoreUnresolvablePlaceholders set to true (i.e.,
spring:propertyname="ignoreUnresolvablePlaceholders" value="true" />
)
=== A Sample Database Creation Script for the JDBC Object Store
-- MySQL Script
CREATE DATABASE saptid_db;
GRANT ALL ON saptid_db.* TO 'sap'@'localhost' IDENTIFIED BY 'secret';
GRANT ALL ON saptid_db.* TO 'sap'@'%' IDENTIFIED BY 'secret';
USE saptid_db;
CREATE TABLE saptids
(
tid VARCHAR(512) PRIMARY KEY,
context TEXT
);
== Outbound Endpoint
The SAP outbound endpoint executes functions (BAPIs) or sends IDocs.
Attribute | Description | Default Value | Since Version |
---|---|---|---|
name |
The reference name of the endpoint used internally by Mule configuration. |
1.0 |
|
exchange-pattern |
The available options are |
1.0 |
|
address |
The standard way to specify endpoint properties. For more information see [Endpoint Address] |
1.0 |
|
type |
The type of SAP object the endpoint will be processing (function or idoc and since 2.1.0, function meta-data) |
function |
1.0 |
rfcType |
Type of RFC the endpoint will use execute a function or send and IDoc. Allowed values are srfc, trfc, and qrfc. |
srfc |
1.0 |
queueName |
If the RFC type is qrfc, then this is the name of the queue. |
1.0 |
|
functionName |
When the type is function, the BAPI function is executed. If the type is function meta-data then you need to provide the name of the BAPI that you want to retrieve its metadata. This attribute accepts [Mule Expressions]. |
1.0 |
|
evaluateFunctionResponse |
When the type is function, this BAPI function is executed. If the type is function meta-data then you need to provide the name of the BAPI that you want to retrieve its metadata. This attribute accepts [Mule Expressions]. |
false |
1.0 |
definitionFile |
The path to the template definition file of either the function to be executed or the IDoc to be sent. |
1.0 |
|
idocVersion |
When the type is idoc, this version is used when sending the IDoc. Values for the IDoc version correspond to IDOC_VERSION_xxxx constants in com.sap.conn.idoc.IDocFactor. |
O (IDOC_VERSION_DEFAULT) |
1.0 |
jcoClient |
The SAP client. This is usually a number (i.e., 100) |
1.0 |
|
jcoUser |
The user for password-based authentication. Since version 2.1.0 this attribute accepts Mule Expressions |
1.0 |
|
jcoPasswd |
The password associated with the user for password-based authentication. Since version 2.1.0 this attribute accepts Mule Expressions. |
1.0 |
|
jcoLang |
The language used by the logon dialogs. When not defined, the default user language is used. |
en |
1.0 |
jcoAsHost |
The SAP application server host (IP or server name). |
1.0 |
|
jcoSysnr |
The SAP system number |
1.0 |
|
jcoPoolCapacity |
The maximum number of idel connections kept open by the destination. No connection pooling takes place when the value is |
5 |
1.0 |
jcoPeakLimit |
The maximum number of active connections that can be created for destination simultaneously. |
10 |
1.0 |
jcoClientExtendedProperties-ref |
A reference to |
1.0 |
|
bapiTransaction |
When set to true, either BAPI_TRANSACTION_COMMIT or BAPI_TRANSACTION_ROLLBACK is called depending if there were excpetions or not. This attribute can be used depending the existence of a transaction. If there is no transaction configured, then BAPI_TRANSACTION_COMMIT is called after executing the function. If there is a transaction, then BAPI_TRANSACTION_COMMIT is called at the end of it. |
false |
2.1.0 |
xmlVersion |
This attribute supports the value 1 or 2 and defines the version of the XML output generated when type is function meta-data |
1 |
2.1.0 |
outputXML |
Whether the endpoint should set payload the XML representation (String) of the SAP Object (Function or IDoc) or the SapObject wrapper itself. Setting this flag to |
false |
2.2.2 |
== Multi User Support
Since SAP Connector version 2.1.0 users can dynamically set connection user and password (This means that both jcoUser and jcoPasswd can be set using a Mule Expression that will be evaluated in runtime). Though this is really useful for use cases where it is important to execute BAPI under a specific user, it is worth mentioning that there will be a pool of connections to SAP created for each user.
Please size correctly the JCo connection pool and configured java memory based on the amount of users that may be used.
== IDoc Versions
Value | Description |
---|---|
0 |
IDOC_VERSION_DEFAULT |
2 |
IDOC_VERSION_2 |
3 |
IDOC_VERSION_3 |
8 |
IDOC_VERSION_QUEUED |
=== A Sample SAP Outbound Endpoint Configuration
<sap:outbound-endpoint exchange-pattern="request-response" type="function" rfcType="qrfc"
queueName="QRFC_QUEUE_NAME" functionName="BAPI_FUNCTION_NAME"
definitionFile="path/to/definition/file.xml"/>
=== A Sample SAP Outbound Endpoint Configuration to retrieve the Metadata for a BAPI (since version 2.1.0)
<sap:outbound-endpoint exchange-pattern="request-response" type="function-metadata" functionName="BAPI_FUNCTION_NAME"/>
== Input Mule Messages
The outbound endpoint expects a Mule Message carrying any of the following payloads:
-
org.mule.transport.sap.SapObject instance. This is a Java POJO, whose two main properties are:
-
type: SapType.FUNCTION (for a BAPI call) or SapType.IDOC (for an IDoc).
-
value: The specific JCo Object depends on the payload type: com.sap.conn.idoc.IDocDocument or com.sap.conn.idoc.IDocDocumentList for IDocs and com.sap.conn.jco.JCoFunction for BAPI calls.
-
-
String, byte[], InputStream instance. The connector will assume that any of these types hold a valid XML representation of a SAP Object (BAPI or IDoc)
-
Any other Object. You need to provide the XML definition with the attribute definitionFile or embedding it in the XML.
The payload can be transformed from a XML string or stream into a SapObject with the following transformers:
<!-- IDocs -->
<sap:xml-to-idoc/>
<!-- BAPI calls -->
<sap:xml-to-function/>
== Embedding the XML Definition
As an alternative to providing the SAP object definition in a file (through the definitionFile attribute), the XML definition can be embedded inside the sap:outbound-endpoint element by using the sap:definition element. As the definition will be an XML fragment, it has to be provided inside a CDATA section.
<sap:outbound-endpoint ...>
<sap:definition>
<![CDATA[
<jco>
<import>
<structure name="POHEADER">
<field name="COMP_CODE">#[payload.value1]</field>
<field name="DOC_TYPE">#[header:value2]</field>
<field name="VENDOR">#[bean:value3]</field>
<field name="PURCH_ORG">#[xpath://path/to/value4]</field>
</structure>
</import>
</jco>
]]>
</sap:definition>
</sap:outbound-endpoint>
== Executing Functions
There are different ways to execute a function:
-
Create an instance of com.sap.conn.jco.JCoFunction and send it as the payload to the SAP outbound-endpoint. In this case, the following attributes will be ignored: type, functionName, definition, definitionFile. You can create the JCoFunction object in a Java component or Script for example.
-
Generate the XML definition for the JCoFunction and send it as the payload (i.e., in one of these formats: InputStream, byte[], or String) to the SAP outbound-endpoint through the <xml-to-function/> transformer. In this case, if the function name is provided in the XML definition, it overrides the value in the attribute functionName. The following attributes are also ignored: type, definition, definitionFile.
-
Configure definitionFile or embed the XML definition in the SAP outbound endpoint. (If both are configured, then the contents of the definitionFile override the embedded XML definition.) The type attribute should be set to function. In this case, if the function name is provided in the XML definition, it overrides the value in the attribute functionName. The XML definition file may contain Mule Expressions that can be substituted at runtime with values present in the Mule Event (payload, headers, global properties, beans, etc.)
Invocation of a function results in a JCoFunction object. The Mule SAP outbound-endpoint wraps this object inside org.mule.transport.sap.SapObject. You can access the response JCoFunction object by invoking the getValue method.
You can also use the <object-to-xml/> transformer to get the XML representation of the JCoFunction.
== Examples
XML Input and XML Output
Example notes:
-
Input is received as an XML document that uses the tag <jco name="BAPI_NAME"> to specify the BAPI to be called.
-
The function output is transformed into a XML document.
-
If the execution of the BAPI by SAP produces an error, an exception is raised from the outbound endpoint (because evaluateFunctionResponse is true).
<mule> ... <sap:connector name="SapConnector" jcoClient="100" jcoUser="mule_test" jcoPasswd="secret" jcoLang="en" jcoAsHost="sapas.mulesoft.com" jcoSysnr="00" jcoTrace="true" jcoPoolCapacity = "3" jcoPeakLimit="10" jcoClientExtendedProperties-ref="sapProperties"/> ... <flow name="sapExample"> ... <xml-to-function/> <sap:outbound-endpoint name="sapOutbound" exchange-pattern="request-response" type="function" rfcType="srfc" evaluateFunctionResponse="true"/> <object-to-xml/> ... </flow> </mule>
== Sending IDocs
There are different ways to send an IDoc:
-
Create an instance of com.sap.conn.idoc.IDocDocument or com.sap.conn.idoc.IDocDocumentList and send it as the payload to the SAP outbound-endpoint. In this case the following attributes will be ignored: type, definition, definitionFile. You can create the IDoc document object in a Java component or Script for example.
-
Generate the XML definition for the IDoc and send it as the payload (InputStream, byte[] or String) to the SAP outbound-endpoint through the <xml-to-idoc/> transformer. In this case the following attributes will be ignored: type, definition, definitionFile.
-
Configure definitionFile or embed the XML definition in the SAP outbound-endpoint. (If both are configured then the contents of the definitionFile will override the embedded XML definition.) The type attribute should be set to idoc. In this case the XML definition file may contain Mule Expressions that can be substituted in runtime with values present in the Mule Event (payload, headers, global properties, beans, etc.)
Reading a file that represents an IDoc (XML Document)
Example notes:
-
This example polls the directory C:/sap-test/in for IDocs XML documents, then sends them to SAP.
-
Extended properties are defined in the map sapProperties.
-
The outbount endpoint is configured with the address attribute.
-
The transformer <sap:xml-to-idoc /> receives a Stream, then transforms it into a SAP Object that the endpoint can process.
<mule xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:spring="http://www.springframework.org/schema/beans" xmlns:sap="http://www.mulesoft.org/schema/mule/sap" xmlns:file="http://www.mulesoft.org/schema/mule/file" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd http://www.mulesoft.org/schema/mule/sap http://www.mulesoft.org/schema/mule/sap/current/mule-sap.xsd"> <spring:bean name="sapProperties" class="java.util.HashMap"> <spring:constructor-arg> <spring:map> <spring:entry key="jco.server.unicode" value="1" /> </spring:map> </spring:constructor-arg> </spring:bean> <sap:connector name="SapConnector" jcoSysnr="00" jcoPeakLimit="10" jcoClientExtendedProperties-ref="sapProperties" /> <file:connector name="FileConnector" moveToDirectory="C:/sap-test/bk" moveToPattern="#[function:datestamp]-#[header:originalFilename]" streaming="false" /> <flow name="sapExample"> <file:inbound-endpoint address="file://C:/sap-test/in" /> <sap:xml-to-idoc /> <sap:outbound-endpoint address="sap://mule_user:password@sapas.mulesoft.com:00?lang=en&jcoClient=100&jcoTrace=false&jcoPoolCapacity=100" exchange-pattern="request-response" type="idoc"/> </flow> </mule>
== Configuring the SAP Connector in Clustered Environments
The SAP connector is Mule HA ready, meaning that it can work in a Mule Cluster without any issues. However, depending on the application architecture, you may need to perform configuration in your SAP endpoints.
The key to a fully working application in cluster is the implementation of [reliability patterns]. |
=== Outbound Endpoint
The outbound endpoint is usually not a problem for HA environment. If the application is correctly built to work in a cluster, then there are no special considerations. Ensure that only one node at a time is processing a specific request. Typically, this is guaranteed by HA-ready inbound endpoints.
=== Inbound Endpoint
The inbound endpoint represents a bigger challenge when configuring your application in HA mode. The following sections provide information that will assist you to make the best decision.
=== Sap Side Functionality
The SAP Connector is based on JCo Server functionality. JCo Server connects a gateway on the SAP side that is responsible for:
-
Load balancing request to the SAP inbound endpoint.
-
In case of Transactional RFCs (rfcType or qRFC), starting the transaction and making sure it doesn’t send the same request to multiple inbound endpoints (and thus avoiding duplicate requests in more than one cluster node).
=== Configuring the SAP Inbound Endpoint for HA
When configuring multiple SAP inbound endpoints in an HA configuration, remember that is that all nodes can share the Transaction IDs (TIDs). For this purpose, configuring a distributed object store based transaction ID store is neccessary. The recommended object store implemenentation for HA configuration is the managed-store, as the default implementation varies depending on whether the application is running standalone or in cluster (shared object store among cluster nodes.)
Also recall that in HA configurations that the payload should be serializable. To ensure this, configure the inbound endpoint to output XML. In 3.5.0, this easily achevied with the outputXML attribute set to true. In previous versions, you need to configure a global transformer.
Mule 3.5.0+
<sap:connector name="SapConnector" jcoAsHost="${sap.jcoAsHost}"
jcoUser="${sap.jcoUser}" jcoPasswd="${sap.jcoPasswd}" jcoSysnr="${sap.jcoSysnr}"
jcoClient="${sap.jcoClient}" jcoLang="${sap.jcoLang}" jcoPoolCapacity="${sap.jcoPoolCapacity}"
jcoPeakLimit="${sap.jcoPeakLimit}"/>
<flow>
<sap:inbound-endpoint type="function" rfcType="trfc" connector-ref="SapConnector"
jcoGwHost="${sap.gwHost}" jcoGwService="${sap.gwService}"
jcoProgramId="${sap.programId}" outputXml="true">
<sap:mule-object-store-tid-store>
<managed-store storeName="sap-tid-store" persistent="true" />
</sap:mule-object-store-tid-store>
</sap:inbound-endpoint>
...
</flow>
Mule 3.4.x and Before
<sap:connector name="SapConnector" jcoAsHost="${sap.jcoAsHost}"
jcoUser="${sap.jcoUser}" jcoPasswd="${sap.jcoPasswd}" jcoSysnr="${sap.jcoSysnr}"
jcoClient="${sap.jcoClient}" jcoLang="${sap.jcoLang}" jcoPoolCapacity="${sap.jcoPoolCapacity}"
jcoPeakLimit="${sap.jcoPeakLimit}"/>
<sap:object-to-xml name="sap-object-to-xml" xmlVersion="2" />
<flow>
<sap:inbound-endpoint type="function" rfcType="trfc" connector-ref="SapConnector"
jcoGwHost="${sap.gwHost}" jcoGwService="${sap.gwService}"
jcoProgramId="${sap.programId}" transformer-refs="sap-object-to-xml">
<sap:mule-object-store-tid-store>
<managed-store storeName="sap-tid-store" persistent="true" />
</sap:mule-object-store-tid-store>
</sap:inbound-endpoint>
...
</flow>
== Transactions
The SAP transport, which is based in JCo, doesn’t support distributed transactions because JCo doesn’t support XA.
The SAP outbound endpoint supports the child element transaction:
<sap:transaction action="ALWAYS_BEGIN" bapiTransaction="true|false"/>
Important Compatibility Notes
Transaction support in the SAP Connector version 1.x is very limited and only transactions of one function call are allowed.
Starting with SAP Connector version 2.1.0, the attribute bapiTransaction
is no longer present at transaction level. This attribute was moved to the outbound endpoint.
Attribute | Description | Default Value | Since Version |
---|---|---|---|
Action |
The action attribute is part of the Mule ESB transaction standard and can have the following values: NONE, ALWAYS_BEGIN, BEGIN_OR_JOIN, ALWAYS_JOIN and JOIN_IF_POSSIBLE |
1.0 |
|
bapiTransaction |
When set to true, either BAPI_TRANSACTION_COMMIT or BAPI_TRANSACTION_ROLLBACK is called at the end of the transaction, depending on the result of that transaction. Since version 2.1.0 this option has being moved to the outbound endpoint. |
false |
1.0 |
For more information, consult the [Transaction Configuration Reference].
Combining the RFC type (rfcType) attributed defined in the outbound endpoint with the transaction facilitates different ways for the SAP transport to handle the transaction:
-
[sRFC stateful]
-
[sRFC stateful BAPI transaction]
-
[tRFC stateful]
-
[qRFC stateful]
For examples, please take a look at [Outbound Endpoint Transactions]
If a transaction is not specified, then all calls (execture function or send IDocs) are stateless. |
== Transformer
-
<sap:xml-to-function/>
-
<sap:xml-to-idoc/>
-
<sap:object-to-xml/>
Attribute | Description | Default Value | Since Version |
---|---|---|---|
xmlVersion |
This attribute supports the value 1 or 2 and defines the version of the XML output generated when type is function-metadata |
1 |
2.2.2 |
== See Also
-
Read about using the [SAP connector in Anypoint™ Studio].
-
Find out more about [SAP JCo Extended Properties], [SAP JCo Server Services Configuration], or [Outbound Endpoint Transactions].
-
Dig deeper into [XML Definitions].
-
Access troubleshooting tips:
-
[Checking log files]
-
[Enabling JCo trace]
-
[Common Errors]
-