Introduction

In my previous post : Reusable Groovy Script to Log Payload as Attachments in CPI , I had described the option to log your Payload as an Attachment. There was also a control to turn on and off logging at a Iflow Level. What if you want to control this at a Tenant Level as well.

Imagine a scenario where you are logging too much data and SAP BTP Operations implements a circuit breaker on your tenant and you have 100’s of Iflows using this approach. What if you want a Global Switch to just turn of your Logging at the tenant level.

Options to have a Global Controller

Global Variable

CPI provides you the option to create a Global Variable and use it across your iflows. You can define a Global Variable called “LogPayloadAsAttachment ” and use this variable to turn the Logging on and off in the reusable Groovy script from previous posts.

While this approach works in principle, there are some strong limitations against this approach

  • Global Variables are stored in SAP Database. So every time you retrieve this variable you perform a Database Operation. Goes without saying DB with the number of times this variable will be used considering this script is going to be called in every of your iflow, and so is this variable, this is a NO NO.
  • Global Variables have a retention period / expiry period and needs to be renewed ( or updated ) every period. While its a minor task for your CPI Operations team, something that makes no sense with the previous limitation in mind.

Value Mapping

Value Mapping is a strong approach to do this. Define a Value Mapping for this LogPayloadAsAttachment and then use this in my Groovy Script. Sounds fun and easy and straight forward and works in most cases. Value Mappings are cached and are not DB Operations but,

  • Imagine a situation where your tenant is unstable because you are logging too much and have too much load on your system. You want to disable logging and hence go to your value mapping and change and try to deploy your Value Mapping change. What is deployment fails? Remember the tenant is unstable and while we see lesser and lesser deployment issues and errors in CPI, this still happens occasionally.
  • ValueMappings are designed to have values that change in every environment, and hence your developers need to have Authorization to change the Value Mapping in Production. All good except they can also change the Value Mapping for this LogPayloadGlobal and maybe you want this to be very restrictive. Only Admins should ideally have control here but as this is a ValueMapping Artifact you open this to multiple developers.

Partner Directory

CPI provides you with Partner Directory to store Partner Information. While this is typically used for B2B Transactions, CPI Partner Directory can also be used for storing Key-Value Pairs.

  • Partner Directory Values are also cached in the runtime and hence there is no performance impact like with Global Variables
  • Partner Directory can be typically updated with APIs and these are Platform APIs of CPI. Hence Authorization is controlled at a Platform API level ( ServiceKeys) and this allows segregation of roles where only Admins can enable and disable this parameter.
  • Partner Directory are not dependent on your CPI runtime and deployment time. They use Platform APIs of SAP and have a different end point typically allowing you to make change to the value without the risk that we covered with Value Mappings.

Now that it is clear ( atleast in my head ) that Partner Directory is the prudent choice here lets move ahead with setting this up.

Create Service Instance & Service Key for Platform APIs

  • Login to your BTP Cockpit and to your CPI Subaccount.
  • You can use a existing ServiceKey as for the ProcessIntegration Runtime -> plan api with role AuthGroup_TenantPartnerDirectoryConfigurator.
  • If you do not have this, Create a Service Instance and Service Key for the Process Integration Runtime -> Plan : api. Give any Instance Name that you would like.

Create Service Instance ( if needed )

Ensure your Service Instance has the role : AuthGroup_TenantPartnerDirectoryConfigurator

Create Service Key ( if needed )

Have the clientId, clientsecret, tokenurl and url copied over.

Create / Update the Partner Directory Variable in Postman

SAP at the moment of writing this blog ( July 2023 ) does not provide any UI for maintaining Partner Directory Entries. I am sure this is somewhere in the roadmap but for now your only option is to use APIs and Postman to create these entries. Ensure you have the following values from your ServiceKey

  • clientid
  • clientsecret
  • url
  • tokenurl

Create StringParameters to create your Partner Directory Variable

  • HTTP End Point: {{url}}/api/v1/StringParameters ( url from your service key)
  • HTTP Operation : POST
  • JSON Payload :
    • Pid : PartnerID,can be any value : CPI in our case
    • Id: Can be any Value: LogPayloadAsAttachment in our case
    • Value: true or false in our case
  • Authorization : Use Bearer token or OAUTH2
{
    "Pid": "CPI",
    "Id": "LogPayloadAsAttachment",
    "Value": "true"
}

Update StringParameters to update your Partner Directory Variable

  • HTTP End Point: {{url}}/api/v1/StringParameters(Pid=’CPI’,Id=’LogPayloadAsAttachment’)
    • URL from your Service Key
    • Pid = Value of PID from Creation of Variable
    • Id = Value of Id from Creation of Variable
  • HTTP Operation : PUT
  • JSON Payload :
    • Pid : PartnerID,can be any value : CPI in our case
    • Id: Can be any Value: LogPayloadAsAttachment in our case
    • Value: true or false in our case
  • Authorization : Use Bearer token or OAUTH2
{
    "Pid": "CPI",
    "Id": "LogPayloadAsAttachment",
    "Value": "false"
}

Update your Groovy Script Collection

The groovy from previous post is updated to now get the PartnerDirectory Value and then use that to check if the Global Flag at a tenant level is enabled to log payload.

import com.sap.gateway.ip.core.customdev.util.Message;
import com.sap.it.api.pd.PartnerDirectoryService;
import com.sap.it.api.ITApiFactory;
import java.util.HashMap;

def Message processData(Message message) {
    def body = message.getBody(java.lang.String) as String
    def map = message.getProperties()
    String LogPayloadAsAttachment = "";
    //Query the PartnerDirectory to get the value of LogPayloadAsAttachment
    //PID : CPI
    //Id: LogPayloadAsAttachment
    def service = ITApiFactory.getApi(PartnerDirectoryService.class, null); 
    if (service == null){
          LogPayloadAsAttachment = "true"
       }
    LogPayloadAsAttachment = service.getParameter("LogPayloadAsAttachment", "CPI" , String.class);
    //Get the StepId of the execution
    def mpl = message.getProperty('SAP_MessageProcessingLog')
    Set mplKeys = mpl.getContainedKeys()
    def stepId = mpl.get(mplKeys.find { it.getName() == 'StepId' })
    //GetAttachmentName Property. If this is not set (NULL), then set AttachmentName to StepId
    String attachmentName = (map?.get("attachmentName")?:stepId)
    //Get Property logPayload. If NULL, set to false
	String logPayload =(map?.get("logPayload")?:'false')
	def messageLog = messageLogFactory.getMessageLog(message)
    if(messageLog != null){
        if(logPayload.equalsIgnoreCase("true") && LogPayloadAsAttachment.equalsIgnoreCase("true")){
            messageLog.addAttachmentAsString(attachmentName, body, "text/plain")
        }
     }
    return message;
}

Turn OFF Logging at Tenant Level

Set the Value as “false” for PartnerDirectory StringParameter as described in previous section.

If you set the value as “false”, no matter what the logPayload value is in your Iflow, the Logging will now not be triggered.

Turn ON Logging at Tenant Level

Set the Value as “true” for PartnerDirectory StringParameter as described in previous section.

If you set the value as true Globally then the Iflow level logPayload takes over and will determine if the payload is to be logged or not.

Final Thoughts

You can turn off Logging at a Tenant Level on the fly without any deployments using a PartnerDirectoryVariable. While no UI exists to view these variables, there are additional CPI Addons ( SuperEasy Extension For SAP CPI ) that provide a UI to view these variables.

The Truth table on how this code works is as listed below and you can now control your logging both at Tenant Level and IFlow Level.