agentsclimarketplace

Sap integration suite advanced

Skill efeumutaslan/SAP-SKILLS/skills/sap-integration-suite-advanced

23 SAP development skills for Claude Code — ABAP, RAP, CAP, Fiori, BTP, HANA, S/4HANA, Integration Suite and more. Agent Skills Specification compatible.

Install
npx -y skills add efeumutaslan/SAP-SKILLS --skill sap-integration-suite-advanced

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Advanced SAP Integration Suite skill. Use when writing Groovy scripts for iFlows, configuring API Management policies, deploying Edge Integration Cell, or building B2B/EDI integrations. If the user mentions CPI Groovy script, API policy, Edge Cell, TPM, or advanced iFlow mapping, use this skill.

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

15.0 KB, as published. Nobody here has run it

Advanced SAP Integration Suite — Groovy, API Mgmt & Edge

Related Skills

  • sap-event-mesh — Event-driven integration patterns
  • sap-s4hana-extensibility — S/4HANA API consumption via Integration Suite
  • sap-security-authorization — OAuth/SAML policies in API Management
  • sap-devops-cicd — Integration content transport and CI/CD

Quick Start

Advanced capabilities:

CapabilityUse CaseKey Feature
Cloud IntegrationA2A, B2B, cloud-to-on-premiFlows, Groovy, mapping
API ManagementAPI facade, rate limiting, analyticsPolicies, Developer Portal
Integration AdvisorB2B message mappingMAG (Message Application Group)
Trading Partner ManagementEDI/B2B partner onboardingAS2, EDIFACT, X12
Edge Integration CellOn-premise/private cloud runtimeKubernetes-based, hybrid
Open Connectors170+ SaaS connectorsPre-built adapters

Core Concepts

iFlow Processing Pipeline

Sender ──► Sender Adapter ──► Integration Flow ──► Receiver Adapter ──► Receiver
                                    │
                    ┌───────────────┼───────────────┐
                    ▼               ▼               ▼
              Content         Message           Router /
              Modifier        Mapping           Splitter
                    │               │               │
                    ▼               ▼               ▼
              Groovy          XSLT /            Aggregator
              Script          Graphical

API Management Policy Types

CategoryPolicyPurpose
TrafficSpike ArrestPrevent traffic spikes
TrafficQuotaLimit calls per time period
TrafficConcurrent Rate LimitMax simultaneous connections
SecurityOAuth v2.0Token validation
SecuritySAML AssertionSAML token validation
SecurityVerify API KeySimple API key auth
MediationJSON to XMLFormat conversion
MediationAssign MessageSet headers/variables
ExtensionJavaScriptCustom policy logic

Edge Integration Cell Architecture

┌─────────────────────────────────────────┐
│  Customer Data Center / Private Cloud    │
│  ┌───────────────────────────────────┐  │
│  │     Edge Integration Cell          │  │
│  │  ┌─────────┐  ┌──────────────┐   │  │
│  │  │ Runtime  │  │ Edge Event   │   │  │
│  │  │ (iFlows) │  │ Broker       │   │  │
│  │  └────┬─────┘  └──────┬───────┘  │  │
│  │       │               │           │  │
│  │  ┌────┴───────────────┴────┐     │  │
│  │  │ Kubernetes (K3s/K8s)    │     │  │
│  │  └─────────────────────────┘     │  │
│  └───────────────┬───────────────────┘  │
│                  │ HTTPS (outbound only) │
└──────────────────┼──────────────────────┘
                   ▼
          SAP Integration Suite
          (Cloud Control Plane)

Common Patterns

Pattern 1: Groovy Script — JSON Transformation

import com.sap.gateway.ip.core.customdev.util.Message
import groovy.json.JsonSlurper
import groovy.json.JsonOutput

def Message processData(Message message) {
    def body = message.getBody(String)
    def json = new JsonSlurper().parseText(body)

    // Transform structure
    def result = json.orders.collect { order ->
        [
            orderNumber: order.id,
            customerName: order.customer?.name ?: 'Unknown',
            totalAmount: order.items?.sum { it.price * it.quantity } ?: 0,
            currency: order.currency ?: 'EUR',
            lineItems: order.items?.collect { item ->
                [
                    materialId: item.productId,
                    description: item.description?.take(40),
                    quantity: item.quantity,
                    unitPrice: item.price
                ]
            } ?: []
        ]
    }

    message.setBody(JsonOutput.toJson([salesOrders: result]))
    message.setHeader('Content-Type', 'application/json')
    message.setProperty('OrderCount', result.size())
    return message
}

Pattern 2: Groovy Script — Error Handling & Logging

import com.sap.gateway.ip.core.customdev.util.Message
import org.apache.camel.Exchange

def Message processData(Message message) {
    def log = messageLogFactory.getMessageLog(message)
    def props = message.getProperties()

    try {
        def body = message.getBody(String)

        // Validate input
        if (!body || body.trim().isEmpty()) {
            throw new IllegalArgumentException("Empty message body")
        }

        // Log for monitoring (appears in Message Processing Log)
        log?.addAttachmentAsString('InputPayload', body, 'application/json')

        // Process...
        def result = transform(body)

        log?.setStringProperty('ProcessingStatus', 'SUCCESS')
        log?.setStringProperty('RecordCount', result.size().toString())

        message.setBody(result)
    } catch (Exception e) {
        // Set error details for exception subprocess
        message.setProperty('ErrorMessage', e.message)
        message.setProperty('ErrorClass', e.class.simpleName)
        message.setProperty('ErrorTimestamp', new Date().format("yyyy-MM-dd'T'HH:mm:ss'Z'"))

        log?.setStringProperty('ProcessingStatus', 'ERROR')
        log?.setStringProperty('ErrorDetail', e.message)

        // Re-throw to trigger error handling
        throw e
    }

    return message
}

Pattern 3: Groovy Script — Dynamic Routing

import com.sap.gateway.ip.core.customdev.util.Message

def Message processData(Message message) {
    def body = new groovy.json.JsonSlurper().parseText(message.getBody(String))

    // Determine route based on payload
    def routeTarget = switch(body.documentType) {
        case 'INVOICE'     -> 'InvoiceEndpoint'
        case 'CREDIT_MEMO' -> 'CreditMemoEndpoint'
        case 'PO'          -> 'PurchaseOrderEndpoint'
        default            -> 'DefaultEndpoint'
    }

    // Set routing header for Router step
    message.setHeader('RouteTarget', routeTarget)

    // Set dynamic endpoint URL
    def endpoints = [
        'InvoiceEndpoint':     'https://erp.example.com/api/invoices',
        'CreditMemoEndpoint':  'https://erp.example.com/api/credit-memos',
        'PurchaseOrderEndpoint': 'https://erp.example.com/api/purchase-orders',
        'DefaultEndpoint':     'https://erp.example.com/api/documents'
    ]
    message.setProperty('DynamicEndpointURL', endpoints[routeTarget])

    return message
}

Pattern 4: API Management — Rate Limiting Policy

<!-- Spike Arrest Policy -->
<SpikeArrest async="false" continueOnError="false" enabled="true"
  xmlns="http://www.sap.com/apimgmt">
  <DisplayName>Spike Arrest - 30ps</DisplayName>
  <Rate>30ps</Rate>  <!-- 30 per second -->
  <Identifier ref="request.header.X-Client-ID"/>
</SpikeArrest>

<!-- Quota Policy (per API key) -->
<Quota async="false" continueOnError="false" enabled="true" type="calendar"
  xmlns="http://www.sap.com/apimgmt">
  <DisplayName>Monthly Quota</DisplayName>
  <Allow count="10000"/>
  <Interval>1</Interval>
  <TimeUnit>month</TimeUnit>
  <StartTime>2026-01-01 00:00:00</StartTime>
  <Identifier ref="request.header.apiKey"/>
  <Distributed>true</Distributed>
</Quota>

<!-- OAuth v2.0 Validation -->
<OAuthV2 async="false" continueOnError="false" enabled="true"
  xmlns="http://www.sap.com/apimgmt">
  <DisplayName>Verify OAuth Token</DisplayName>
  <Operation>VerifyAccessToken</Operation>
  <AccessToken>request.header.Authorization</AccessToken>
  <Scope>read write</Scope>
</OAuthV2>

<!-- Response Caching -->
<ResponseCache async="false" continueOnError="false" enabled="true"
  xmlns="http://www.sap.com/apimgmt">
  <DisplayName>Cache GET responses</DisplayName>
  <CacheKey>
    <KeyFragment ref="request.uri"/>
    <KeyFragment ref="request.header.Accept"/>
  </CacheKey>
  <ExpirySettings>
    <TimeoutInSec>300</TimeoutInSec>
  </ExpirySettings>
  <SkipCacheLookup>request.verb != "GET"</SkipCacheLookup>
</ResponseCache>

Pattern 5: XSLT Mapping — IDoc to JSON

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:idoc="urn:sap-com:document:sap:idoc:messages">

  <xsl:output method="text" encoding="UTF-8"/>

  <xsl:template match="/">
    <xsl:text>{"orders":[</xsl:text>
    <xsl:for-each select="//ORDERS05/IDOC">
      <xsl:if test="position() > 1">,</xsl:if>
      <xsl:text>{"orderNumber":"</xsl:text>
      <xsl:value-of select="E1EDK01/BELNR"/>
      <xsl:text>","orderDate":"</xsl:text>
      <xsl:value-of select="concat(
        substring(E1EDK01/DATUM,1,4),'-',
        substring(E1EDK01/DATUM,5,2),'-',
        substring(E1EDK01/DATUM,7,2))"/>
      <xsl:text>","items":[</xsl:text>
      <xsl:for-each select="E1EDP01">
        <xsl:if test="position() > 1">,</xsl:if>
        <xsl:text>{"lineItem":"</xsl:text>
        <xsl:value-of select="POSEX"/>
        <xsl:text>","material":"</xsl:text>
        <xsl:value-of select="normalize-space(MATNR)"/>
        <xsl:text>","quantity":</xsl:text>
        <xsl:value-of select="MENGE"/>
        <xsl:text>}</xsl:text>
      </xsl:for-each>
      <xsl:text>]}</xsl:text>
    </xsl:for-each>
    <xsl:text>]}</xsl:text>
  </xsl:template>
</xsl:stylesheet>

Pattern 6: B2B Integration — AS2 with TPM

Trading Partner Setup:
┌──────────────┐    AS2/HTTPS    ┌──────────────────┐
│   Partner A   │───────────────►│  Integration Suite │
│  (Supplier)   │  EDIFACT msg   │  ┌──────────────┐ │
│               │◄───────────────│  │  TPM Config   │ │
└──────────────┘    AS2 MDN      │  │  - Partner ID │ │
                                 │  │  - AS2 ID     │ │
                                 │  │  - Certificate│ │
                                 │  │  - Agreement  │ │
                                 │  └──────┬───────┘ │
                                 │         ▼         │
                                 │  ┌──────────────┐ │
                                 │  │  iFlow        │ │
                                 │  │  (EDI→XML→    │ │
                                 │  │   IDoc/OData) │ │
                                 │  └──────┬───────┘ │
                                 └─────────┼─────────┘
                                           ▼
                                    SAP S/4HANA

TPM Configuration checklist:

  1. Create Trading Partner profile (AS2 ID, certificates)
  2. Define Agreement (message type: ORDERS, INVOIC, DESADV)
  3. Configure B2B adapter in iFlow (AS2 sender/receiver)
  4. Map EDI segments to SAP IDoc/API structure
  5. Set up MDN (Message Disposition Notification) for acknowledgment
  6. Test with partner's test environment before go-live

Error Catalog

ErrorContextRoot CauseFix
Groovy: NullPointerExceptionScript stepAccessing null propertyAdd null-safe operator ?. and default values
Groovy: ClassNotFoundExceptionCustom libraryJAR not uploaded to tenantUpload via Integration Content → Resources
HTTP 429API ManagementRate limit/quota exceededAdjust policy; contact API provider
MPL: FAILEDMessage Processing LogiFlow step errorCheck MPL attachments and trace for root cause
Certificate expiredReceiver adapterSSL/TLS cert expirationRotate certificate in Security Material
AS2: MDN negativeB2BPartner rejected messageCheck EDI validation; verify message structure
Mapping errorMessage MappingSource/target mismatchCompare source XML structure with mapping definition
Edge: Pod CrashLoopBackOffEdge Integration CellMemory/config issueCheck pod logs; increase resource limits
Credential not foundAdapter authMissing Security MaterialDeploy OAuth/Basic auth credentials to tenant
Queue fullJMS adapterConsumer too slowScale consumer iFlow; increase queue depth

Performance Tips

  1. Groovy: Reuse parsers — Compile JsonSlurper once, reuse across messages; avoid new in hot paths
  2. Streaming for large payloads — Use Groovy XMLStreamReader instead of DOM for >10 MB XML
  3. Content Modifier over Script — Use Content Modifier for simple header/property changes; Groovy adds overhead
  4. JMS queues for decoupling — Use JMS between sender and receiver iFlows for retry and buffering
  5. API caching — Enable ResponseCache policy for read-heavy APIs; 5-min cache reduces backend calls 80%+
  6. Parallel processing — Use Splitter (parallel) + Aggregator for batch processing
  7. Edge Cell for latency — Deploy latency-sensitive iFlows to Edge; keep cloud for management only
  8. Minimize trace logging — Trace-level logging in production impacts throughput; use only for debugging

Gotchas

  • Groovy sandbox: Integration Suite Groovy runs in a restricted sandbox — no file I/O, no network calls (use adapters)
  • Groovy version: Integration Suite uses Groovy 2.4.x (not 4.x); avoid newer syntax
  • iFlow versioning: Each deploy creates a new version; rollback by redeploying older version
  • Edge Cell updates: Edge runtime must be kept within 2 versions of cloud; auto-update recommended
  • API proxy vs. iFlow: API Management proxies are for facade/security; iFlows for transformation/routing
  • JMS queue limits: Default 30 queues per tenant; each 9.3 GB max; request increase via support ticket
  • B2B certificates: Partner certificates expire; set calendar reminders for rotation

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.