Skip to Content

Partner Directory – Step-by-Step Example

We explain the use cases for using the Partner Directory in an integration flow and elaborate a step-by-step example which you can configure in your SAP Cloud Integration tenant.

The Partner Directory is used in integration scenarios where you establish a communication network between many communication partners. In such kind of scenarios, you build one or a few integration flows which are parametrized by partner-specific information. The parametrized components in the integration flow read the partner-specific information from the Partner Directory. The Partner Directory contains for each partner parameters, like

  • the Authorized User which is authorized to call inbound endpoints of the integration flow(s),
  • the HTTP addresses needed for making outbound calls to the partner systems.

With the Partner Directory, it is possible to add new communication partners without downtime and without changing or redeploying the integration flows. The tenant administrator or Partner Directory configurator can enter entries of a new partner into the Partner Directory via an OData API while the message processing for the existing partners is ongoing.

Figure 1: Partner Directory Usage Scenario

Message Dependent Parameter Lookup

In scenarios where the Partner Directory is involved, the messages sent to the integration flow(s) typically contain information that is needed for looking-up the parameters from the Partner Directory. For example, if the sent message contains the receiver partner ID then the receiver address can be looked-up.

Figure 2: : Message Containing the Partner IDs for Which Parameters Must be Looked-Up in the Partner Directory

Accessing Parameters in a Script Step

The Partner Directory does not predefine which parameters must be specified for a partner. The Integration Developer decides which parameter names (also called IDs) he wants to use. In a script step then the parameter value can be accessed by the partner ID contained in the message and the parameter ID.

Figure 3: Accessing Parameters via Script Using the Partner ID Given in the Message and the Hard Coded Parameter ID

There are length and character restrictions for the partner ID and parameter ID.

Maximum length of the partner ID: 60 characters

Maximum length of the parameter ID: 1500 characters

Allowed characters for the partner ID and parameter ID: ALPHA / DIGIT / ‘-‘ / ‘.‘ / ‘_‘ / ‘~‘ / ‘<‘ / ‘>‘ where ALPHA =(%41-%5A and %61-%7A in ASCII), DIGIT=(%30-%39 in ASCII)

Sometimes the messages contain IDs for the partners which must be mapped to the partner IDs of the Partner Directory. This use case will be treated in a separate blog.

Example Scenario

In our example scenario, we differentiate between sender and receiver communication partners. Sender communication partners make calls to receiver communication partners via the SAP Cloud Integration tenant and receiver partners receive calls from the sender communication partners via the tenant. This makes it easier to understand what you configure for partners making inbound calls to the tenant and for partners which receive outbound calls from the tenant. There may be scenarios where the sender and receiver partner are the same entity; in this case you do not need to have separate partner IDs for the sender and receiver parameters.

We will set-up a scenario where we have the two sender partners with the partner IDs “Sender_BASIC” and “Sender_OAUTH” and the two receiver partners with the partner IDs “Receiver_1” and “Receiver_2”.

The senders will send HTTP messages with the format given in Figure 2 to the Cloud Integration tenant. The tenant will forward the message to the receiver partner specified in the message.

The receiver partners are represented by two simple integration flows which just return in the content element of the message the receiver partner ID with a greeting text. These receiver integration flows will be created in a separate receiver tenant. If you only have one tenant, you can also create the receiver integration flows in the same tenant where the Partner Directory integration flow is located. But we recommend to use two separate tenants; then it is easier to understand what must be configured for the integration flow using the Partner Directory (also called Partner Directory integration flow).

The sender partners are simulated by Google PostMan.

 

Figure 4: Example Scenario

Prerequisites

To be able to set-up the scenario, you need

  • two SAP Cloud Integration tenants (one for the Partner Directory integration flow and the other one for the receiver integration integration flows); it is also possible to use only one tenant; however, then you cannot so easily see what you have configured for the Partner Directory integration flow and what you have configured for the receiver integration integration flows.
  • a Tenant Administrator user in both tenants which has Administrator permission in the SAP Cloud Platform Cockpit and which has the Role AuthGroup.Adminstrator on the tenant management node (tmn) application of your integration tenants
  • an Integration Developer user in both tenants which can create and deploy integration flows (Role AuthGroup.IntegrationDeveloper on tmn application of your integration tenant),
  • a further user which will be used for sending messages to the Partner Directory tenant (you can also use the Integration Developer or Tenant Administrator user instead); in the following sections, we will call this user Communication user
  • an appropriately configured tenant keystore of the Partner Directory; the keystore must contain a key-pair which is signed by a CA which is accepted by the Loadbalancer of the SAP Cloud Integration Platform (typically SAP pre-installs such kind of key-pair with the alias “sap_cloudintegrationcertificate” or “hcicertificate”)
  • Google PostMan installed on your local machine for sending messages to the integration tenant

Step 1: Creating Receiver Integration Flows

In the receiver tenant create an integration flow with the sender channel and a Content Modifier step as shown in the following screen shots.

Figure 5: Receiver Integration Flow

Figure 6: Receiver Integration Flow SOAP 1.x Sender Channel General Tab

Figure 7: Receiver Integration Flow, SOAP 1.x Sender Channel, Connection Tab (be aware that we use as User Role “receiver_1.send”; for the second receiver integration flow you have to use “receiver_2.send”)

Figure 8: Content Modifier Exchange, Property Tab

Figure 9: Receiver Integration Flow, Content Modifier, Message Body Tab

Deploy the integration flow and test with PostMan whether the integration flow works. Do not forget to create the role “receive_1.send” and assign the Communication User (which can be the Integration Developer user or Tenant Administrator user) in the SAP Cloud Platform Cockpit. See the following screen shot.

Figure 10: Assigning the role “receiver_1.send” to the Communication User

You find the endpoint URL you use in PostMan in the SAP Cloud Integration Cockpit in the Operations View > Manage Integration Content > <receiver integration flow name>:

Figure 11: Receiver Endpoint Address is Displayed in the SAP Cloud Integration Cockpit

Figure 12: Test with PostMan the Receiver Integration Flow (do not forget to enter the user and password in the Authorization Tab)

Make sure that you wrap the message body the SOAP envelop.The following figure shows the test message you can use in PostMan:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <Message>
         <SenderPartnerId>Test</SenderPartnerId>
         <ReceiverPartnerId>does not matter</ReceiverPartnerId>
         <Content>test</Content>
      </Message>
   </soapenv:Body>
</soapenv:Envelope>

Message 1: SOAP Message

Create a similar receiver integration flow for the “Receiver_2” partner. Use the endpoint address “/receiver_2” instead of the endpoint address “/receiver_1” and instead of the role “receiver_1.send” use “receiver_2.send”. In the Content Modifier use in the body “Receiver_2” instead of “Receiver_1”.

Step 2: Creating Partner Directory Integration Flow

The following screen shots show how you create an integration flow which makes look-ups into the Partner Directory in a script step to set the receiver partner-dependent receiver address.

Figure 13: Partner Directory Integration Flow

Figure 14: Configuration of the HTTPS Sender Channel

Figure 15: Content Modifier Configuration (the content modifier reads the sender and receiver partner ID contained in the message into the properties SENDER_ID and RECEIVER_ID)

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import com.sap.it.api.pd.PartnerDirectoryService;
import com.sap.it.api.ITApiFactory;
def Message processData(Message message) {
       def service = ITApiFactory.getApi(PartnerDirectoryService.class, null); 
       if (service == null){
          throw new IllegalStateException("Partner Directory Service not found");
       }
       def map = message.getProperties();
       def receiverId = map.get("RECEIVER_ID");
       if (receiverId == null){
          throw new IllegalStateException("Receiver ID is not set in the property 'RECEIVER_ID'")      
       }

     def parameterValue = service.getParameter("ADDRESS", receiverId , String.class);
     if (parameterValue == null){
        throw new IllegalStateException("ADDRESS parameter not found in the Partner Directory for the partner ID "+receiverId);      
     }

      message.setProperty("RECEIVER_ADDRESS", parameterValue );

       return message;
}

Groovy Script 1: Fetches the Receiver Partner ID from the Property “RECEIVER_ID”, Reads the Receiver Address from the Partner Directory and Sets the Receiver Address as Property “RECEIVER_ADDRESS”

Figure 16: Configuration of the SOAP 1.x Receiver Channel (the address is dynamically read from the property “RECEIVER_ADDRESS”)

Step 3: Adding Partner Information to the Partner Directory

Now, we are ready to add the parameters for the partners “Sender_BASIC” and “Receiver_1” to the Partner Directory. The tenant administrator or a user with the role AuthGroup.PartnerDirectoryConfigurator can do this via the OData API.

The OData calls must be made to your tmn node which has the format

https://<tenant short name>-tmn.<ssl_host_name>.hana.ondemand.com/api

In the following we will use for this address the abbreviation

https://<tmn>/api

The Partner Directory OData API is protected against XCSRF attacks. Therefore, you fetch first a X-CSRF-Token before you make create/change/delete requests. See chapter “Authentication” in https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-US/a617d6f37ddc43db8eeb1279662ed5c2.html.

Figure 17: Fetching the X-CSRF-Token (be aware that the token is returned in the header “X-CSRF-Token”)

You enter this token into all the following create/change/delete requests for the header “X-CSRF-Token”. The token can be reused for about 30 minutes. When the token is no longer valid you create a new one with the above call.

Step 3.1 Creating/Updating/Deleting a String Parameter Entry

We provide here a detailed description how to create/update and delete String Parameter entries via OData requests. The possible OData Requests for the entity type String Parameter are also described in https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-US/47b69992cd944e93903d46d700ec682f.html.

The following screen shot shows how you create a String Parameter entry in the Partner Directory which can be looked up in the script step of the Partner Directory integration flow.

Figure 18: Creating Partner Directory Entry of Type String Parameter (make sure that you enter for “https//<receiver_iflmap>/cxf/receiver_1” the endpoint address of the Receiver_1 partner)

Make sure that you set the headers X-CSRF-Token, Content-Type, and Accept before you make the call:

Figure 19: HTTP Headers for the OData Call

You can also change the value of a StringParameter by executing a PUT call: Use the HTTP address

https://<tmn>/api/v1/StringParameters(Pid=’Receiver_1’,Id=’ADDRESS’)

with the request body

{"Value": "https://<receiver_iflmap>/cxf/receiver_1"}

This will change the value of the String Parameter with the partner ID “Receiver_1” and the parameter ID “ADDRESS”.

If you get as return code 204, then the update was successful.

Additionally, you can delete the entry using the HTTP DELETE method for the HTTP address

https://<tmn>/api/v1/StringParameters(Pid=’Receiver_1’,Id=’ADDRESS’)

Step 3.2 Authorized User

Another important entity type of the Partner Directory is the Authorized User. An Authorized User entry assigns a communication user to a partner ID. A communication user can only be assigned to exactly one partner ID, but a partner ID can have several communication users. When an Authorized User entry is created, automatically the role ESBMessaging.send is assigned to the user in the (worker node) application (iflmap), so that this communication user can execute inbound calls to an integration flow.

Perform a POST call to the address

https://<tmn>/api/v1/AuthorizedUsers

with the body

{"Pid":"Sender_BASIC","User":"<your communication user>"}

to create an Authorized User entry for the partner “Sender_BASIC”. As communication user you can either use the Tenant Administrator user, or the Integration Developer user, or a separate user you created in the SAP Cloud Identity Provider.

For updating an Authorized User entry use a HTTP PUT method with address

https://<tmn>/api/v1/AuthorizedUsers(‘<your communication user>’)

and body part

{"Pid":"<your updated partner ID"}

Additionally, for deleting an Authorized User entry use a HTTP DELETE method.

After you created the Authorized User entry, check in the SAP Cloud Platform Cockpit that the user-role assignment exists.

Step 4: Exchanging Client Certificate with the Receivers

We use client-certificate authentication for the calls from the Partner Directory integration flow to the receivers. Therefore, we have to exchange the client certificate with the receivers so that a certificate-user mapping can be performed on the receiver tenant.

Go to the SAP Cloud Platform Integration Cockpit of your tenant where the Partner Directory integration flow is running and navigate to Monitor > Keystore

Choose the entry with the alias “hcicertificate” or “sap_cloudintegrationcertificate” and select the button for the entry actions. Choose “Download Certificate”.

This will download the X.509 Certificate for the key-pair.

This certificate is used for creating a certificate-user mapping in the receiver tenant. Now go to the SAP Cloud Integration Platform Cockpit of the receiver tenant and navigate to Monitor > Certificate-To-User Mappings.

Add a certificate-user mapping by uploading the client certificate. As user name use “client_cert_user_pd_test“.

Create the roles “receiver_1.send” and “receiver_2.send” in the SAP Cloud Platform Cockpit of the receiver tenant, if they do not yet exist.

Assign the role “receiver_1.send” and “receiver_2.send” to the user “client_cert_user_pd_test” in the SAP Cloud Platform Cockpit of the receiver tenant.

Figure 20: Creation and Assignment of the roles “receiver_1.send” and “receiver_2.send” to the user “client_cert_user_pd_test” (which is the user from the certificate-user mapping)

Step 5: Call the Integration Flow

The communication user can now call the integration flow. We use PostMan to make a call to the Partner Directory integration flow using the endpoint URL https://<iflmap>/http/partner_directory_test where <iflmap> is the path of your iflmap node. Use as request body the following message.

<Message>
    <SenderPartnerId>Sender_BASIC</SenderPartnerId>
    <ReceiverPartnerId>Receiver_2</ReceiverPartnerId>
    <Content>test</Content>
</Message>

Message 2: Request Message for Calling Receiver_1

Figure 21: Calling the Endpoint of the Partner Directory Integration Flow in PostMan (make sure that you use user-password authorization for the communication user)

If you have also configured in the Partner Directory the String Parameter entries for the “Receiver_2” partner ID (See Figure 12, just exchange “Receiver_1” by “Receiver_2” and use the address of “Receiver_2), then you can also execute a call to Receiver_2. Just use the following request message body:

<Message>
    <SenderPartnerId>Sender_BASIC</SenderPartnerId>
    <ReceiverPartnerId>Receiver_2</ReceiverPartnerId>
    <Content>test</Content>
</Message>

Message 3: Request Message for Calling Receiver_2

 

Step 6: Introducing a Second Sender Partner Using OAuth

We want to introduce a second sender partner which will use OAuth with Client Credential Grant for connecting to the SAP Cloud Integration tenant.

Step 6.1 Register OAuth Client

The following screen shots describe how you can set-up OAuth with Client Credential Grant.

As Tenant administrator you go to the SAP Cloud Platform Cockpit of the tenant containing the Partner Directory integration flow.

In the Security OAuth section, go to the Clients tab and press the button Register New Client.

As client name enter “CLIENT_SENDER_OAUTH”. Select the correct subscription (which contains typically the iflmap application).

Enter as ID also “CLIENT_SENDER_OAUTH”.

Choose the Authorization Grant “Client Credentials”.

Enter a password in the Secret field.

And keep the lifetime to 60 minutes.

Figure 22: Creating OAuth Client with Client Credential Grant

From the Banding tab you get the URL for accessing the OAuth token. It has the format

https://oauthasservices-<consumer-account>.<landscape host name>/oauth2/api/v1/token

Remember this address you will need it when you want to make a OAuth call.

How you configure OAuth with Client Credential grant is also described in https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-US/cf611eca57744d29be588b7d4ec900e1.html (you must not perform the second step with the title “Assign the user with name oauth_client_<client ID>” because this step is done automatically when you create the Authorized User in the Partner Directory).

Step 6.2 Create Authorized User for OAuth User

If you make calls with OAuth using Client Credential Grant to the SAP Cloud Integration tenant, a user with the name “oauth_client_<client ID>” is logged in. In our example the user name is “oauth_client_CLIENT_SENDER_OAUTH”.

Therefore, we create an Authorized User entity with the user property value “oauth_client_CLIENT_SENDER_OAUTH”.

In PostMan, execute an OData POST call to

https://<tmn>/api/v1/AuthorizedUsers

with the body

{"Pid":"Sender_OAUTH","User":"oauth_client_CLIENT_SENDER_OAUTH"}

Do not forget to create the X-CSRF-Token before.

This binds the user “oauth_client_CLIENT_SENDER_OAUTH” to the partner ID “Sender_OAUTH” and creates an assignment of the user to the role ESBMessaging.send in the application iflmap.

You should check in the SAP Cloud Platform Cockpit of your tenant whether this assignment was successful.

Step 6.3 Calling the Partner Directory Integration Flow with OAuth Sender

Before we can call the Partner Directory integration flow with OAuth, we have to fetch the OAuth token. For this we need the token URI we looked up in step 6.1 in the Branding tab. We have to enrich the URI with the query part “?grant_type=client_credentials”; so the full URI has the format as follows:

 https://oauthasservices-<consumer-account>.<landscape host name>/oauth2/api/v1/token?grant_type=client_credentials

Use PostMan to perform a POST HTTPS call to this URI with basic authentication where the client ID is the user and the secret is the password. This call returns the access token.

Figure 23: Creating the OAuth token (the value of the field access_token contains the OAuth token)

Finally, perform an HTTPS call to the endpoint URI

https://<iflmap>/http/partner_directory_test

with the HTTP header with name “Authorization” and value “Bearer <access_token>”.

Figure 24: OAuth Call to Partner Directory Integration Flow

Step 7: Solution to the Security Problem – Sender Partner can Pretend to be Another Sender Partner – Partner Authorization

If more than one sender can call an integration flow endpoint, then you must ensure that a sender cannot pretend to be another sender. With the configuration so far, this is not ensured in our integration flow. For example, you can try to make a OAuth call as specified in Step 6.3 with the following message

<Message>
    <SenderPartnerId>Sender_BASIC</SenderPartnerId>
    <ReceiverPartnerId>Receiver_2</ReceiverPartnerId>
    <Content>test</Content>
</Message>

Message 4: Message for Pretending to be a Sender Partner with ID “Sender_BASIC”

This call will succeed although we are using the OAuth user “oauth_client_CLIENT_SENDER_OAUTH” which is the user of the partner with ID “Sender_OAUTH”.

The user “oauth_client_CLIENT_SENDER_OAUTH” should only be able sending messages with SenderPartnerId value “Sender_OAUTH” and the basic authentication communication user should only be able sending messages with SenderPartnerId value “Sender_BASIC”. Otherwise we have a security problem.

To overcome this security problem, we must check that users can only sent messages which contain in the SenderPartnerId element the partner ID which is specified in the corresponding AuthorizedUser entry of the Partner Directory. We call this check Partner Authorization.

For the Partner Authorization, we make two changes in the Partner Directory integration flow.

  • We add the header name “SapAuthenticatedUserName” to the allowed headers, so that the logged-in user will be forwarded to the integration flow in this headerFigure 25: Add to the Runtime Configuration the Allowed HeaderSapAuthenticatedUserName
  • We enhance the script step with the Partner Authorization:
    import com.sap.gateway.ip.core.customdev.util.Message;
    import java.util.HashMap;
    import com.sap.it.api.pd.PartnerDirectoryService;
    import com.sap.it.api.ITApiFactory;
    def Message processData(Message message) {
           def service = ITApiFactory.getApi(PartnerDirectoryService.class, null); 
           if (service == null){
              throw new IllegalStateException("Partner Directory Service not found");
           }
           def map = message.getProperties();
           // Partner Authorization
           def headers = message.getHeaders();
           def user = headers.get("SapAuthenticatedUserName");
           if (user == null){
              throw new IllegalStateException("User is not set in the header 'SapAuthenticatedUserName'")      
           }
          def senderPid = service.getPartnerIdOfAuthorizedUser(user);
           if (senderPid == null){
    		   throw new IllegalStateException("No partner ID found for user "+user);
           }
           def senderId = map.get("SENDER_ID");
           if (senderId == null){
              throw new IllegalStateException("Sender ID is not set in the property 'SENDER_ID'")      
           }
            // compare the two sender partner IDs!
           if (!senderId.equals(senderPid )){
    	    throw new IllegalStateException("User "+user+" is not authorized to send messages with ID "+senderId);
          } 
           // RECEIVER_ADDRESS determination
           def receiverId = map.get("RECEIVER_ID");
           if (receiverId == null){
              throw new IllegalStateException("Receiver ID is not set in the property 'RECEIVER_ID'")      
           }
         def parameterValue = service.getParameter("ADDRESS", receiverId , String.class);
         if (parameterValue == null){
            throw new IllegalStateException("ADDRESS parameter not found in the Partner Directory for the partner ID "+receiverId);      
         }
          message.setProperty("RECEIVER_ADDRESS", parameterValue );
           return message;
    }
    ​

    Groovy Script 2: Enhanced Script with Partner Authorization

If you now try to send with the user “oauth_client_CLIENT_SENDER_OAUTH” a message with the SenderPartnerId value “Sender_BASIC”, you will get the error

“An internal server error occured: java.lang.IllegalStateException: User oauth_client_CLIENT_SENDER_OAUTH is not authorized to send messages with ID Sender_BASIC”

 

Further Reading

There are further blogs about the Partner Directory.

The blog Partner Dependent XML Structures and- IDs covers the topics

  • Dynamic selection of XSLT files from the Partner Directory
  • Dynamic selection of XSD files from the Partner Directory
  • Mapping of external Partner IDs to internal Partner IDs – Alternative Partner IDs

The blog Sender Partner Connecting with Client Certificate Authentication describes how you can configure the Partner Directory for a sender partner connecting via client-certificate authentication to the integration flow.

The blog Partner Dependent User Credential Selection explains how you can call receiver partners with BASIC authentication.

The blog Mass Configuration informs about the use case where you need mass updates for Partner Directory entries executed in one transaction.

To report this post you need to login first.

6 Comments

You must be Logged on to comment or reply to a post.

  1. SaravanaPerumalRaj Chandrabose

    Hi Franz,

    Thanks for this excellent blog , this partner directory helps in managing all the integration partner in in a single place.

    Just to extend this further , I have an idea to build an UI5 / Fiori App on top of this APIs to ensure we don’t depend on Postman Services to update this Partner Directory.

    Any suggestions on how APIs can be brought into SAP WebIDE.

    Thanks

    Regards

    Saravana

     

    (0) 
    1. Franz Forsthofer Post author

      Hi Saravana,

      the Web based UI for filling content for the Partner Directory is on our roadmap. However, many users of the Partner Directory build their own UI  on the given OData API, so that they can design a UI specific to their use case.

      Best Regards Franz

      (1) 
  2. Bhuvanesh Rajpurohit

    Hi Franz,

     

    Thanks for this detailed Blog. PD is an awesome feature of SCI. I am using this in re-designing our solution and it is very helpful. I am awaiting your further blog on using XSLT mappings 🙂

     

    Cheers!

    Bhuvan

    (0) 

Leave a Reply