Skip to main content

sap-event-mesh

SAP Event Mesh and Advanced Event Mesh skill for event-driven architecture on BTP. Use when publishing/consuming S/4HANA business events, configuring queues/topics, working with CloudEvents, or building event-driven microservices with CAP. If the user mentions Event Mesh, SAP business events, CloudEvents, message queue on BTP, or event-driven SAP integration, use this skill.

跳到安装

来源信息

仓库
efeumutaslan/SAP-SKILLS
最近来源活动
2026年3月24日 21:17
检测到的 SKILL.md 语言
英语
星标
5
分支
1

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

文件资源管理器
3 个文件

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
sap-event-mesh
description
SAP Event Mesh and Advanced Event Mesh skill for event-driven architecture on BTP. Use when publishing/consuming S/4HANA business events, configuring queues/topics, working with CloudEvents, or building event-driven microservices with CAP. If the user mentions Event Mesh, SAP business events, CloudEvents, message queue on BTP, or event-driven SAP integration, use this skill.
license
MIT
metadata
{"author":"SAP Skills Community","version":"1.0.0","last_verified":"2026-03-24"}
# SAP Event Mesh & Event-Driven Architecture ## Related Skills - `sap-kyma-runtime` — Event-driven Functions on Kyma consuming Event Mesh - `sap-s4hana-extensibility` — S/4HANA business events as event sources - `sap-build-process-automation` — Trigger workflows from events ## Quick Start **Choose your event broker:** | Broker | Use Case | Protocol | Scale | |--------|----------|----------|-------| | **SAP Event Mesh** | BTP-native events, simple pub/sub | AMQP 1.0, REST, MQTT | Standard workloads | | **Advanced Event Mesh** | Enterprise event mesh, multi-cloud | AMQP, MQTT, REST, SMF, JMS, WebSocket | High throughput, global | **Minimal CAP event producer:** ```javascript // srv/order-service.js const cds = require('@sap/cds'); module.exports = class OrderService extends cds.ApplicationService { async init() { this.after('CREATE', 'Orders', async (order) => { const msg = await cds.connect.to('messaging'); await msg.emit('sap/sales/order/created/v1', { orderId: order.ID, customer: order.customer_ID, total: order.total }); }); await super.init(); } }; ``` ## Core Concepts ### CloudEvents Specification SAP Event Mesh uses CloudEvents 1.0 standard: ```json { "specversion": "1.0", "type": "sap.s4.beh.salesorder.v1.SalesOrder.Created.v1", "source": "/default/sap.s4.beh/S4HANA_CLD", "id": "a1b2c3d4-5678-90ab-cdef", "time": "2026-03-24T10:00:00Z", "datacontenttype": "application/json", "data": { "SalesOrder": "1000001", "SalesOrganization": "1010", "SoldToParty": "CUST001" } } ``` ### Topic Naming Convention ``` {namespace}/{business-object}/{event-type}/{version} Examples: sap.s4.beh/salesorder/created/v1 sap.s4.beh/businesspartner/changed/v1 custom/myapp/order/fulfilled/v1 ``` **Hierarchy rules:** - Use `/` as level separator - Wildcards: `+` (single level), `*` (multi-level) — for subscriptions only - Subscription example: `sap/s4/beh/+/created/v1` matches all "created" events ### Event Mesh Architecture ``` S/4HANA ──► Enterprise Messaging ──► Event Mesh ──► Consumers │ BTP Apps ──► CAP Messaging ────────────┘ ┌── BTP App (webhook) ├── Kyma Function External ──► REST/AMQP ───────────────────────├── Integration Flow └── Queue → Worker ``` ### Queue vs. Topic | Aspect | Topic | Queue | |--------|-------|-------| | Delivery | Pub/sub (1-to-many) | Point-to-point (1-to-1) | | Persistence | Not persistent | Messages persisted until consumed | | Pattern | Events, notifications | Task processing, reliable delivery | | Subscription | Topic filter with wildcards | Direct queue binding | ## Common Patterns ### Pattern 1: Event Mesh Service Instance (BTP) ```json // mta.yaml resource { "name": "event-mesh", "type": "org.cloudfoundry.managed-service", "parameters": { "service": "enterprise-messaging", "service-plan": "default", "path": "./event-mesh.json" } } ``` ```json // event-mesh.json { "emname": "my-app-events", "namespace": "custom/myapp", "version": "1.0.0", "options": { "management": true, "messagingrest": true, "messaging": true }, "rules": { "topicRules": { "publishFilter": ["${namespace}/order/*"], "subscribeFilter": ["${namespace}/order/*", "sap/s4/beh/+/created/v1"] }, "queueRules": { "publishFilter": ["${namespace}/*"], "subscribeFilter": ["${namespace}/*"] } } } ``` ### Pattern 2: CAP Event Consumer ```javascript // srv/event-handler.js const cds = require('@sap/cds'); module.exports = async (srv) => { const msg = await cds.connect.to('messaging'); // Subscribe to S/4HANA business partner events msg.on('sap/s4/beh/businesspartner/changed/v1', async (event) => { const { BusinessPartner } = event.data; console.log(`BP changed: ${BusinessPartner}`); // Sync to local replica const { BusinessPartners } = srv.entities; const bpData = await fetchBPFromS4(BusinessPartner); await cds.run(UPSERT.into(BusinessPartners).entries(bpData)); }); // Subscribe with wildcard msg.on('custom/myapp/order/+/v1', async (event) => { console.log(`Order event: ${event.headers.type}`, event.data); }); }; ``` ```json // package.json — messaging config { "cds": { "requires": { "messaging": { "kind": "enterprise-messaging", "format": "cloudevents", "publishPrefix": "custom/myapp/", "subscribePrefix": "custom/myapp/" } } } } ``` ### Pattern 3: REST API — Publish Event ```python import requests import json def publish_event(token_url, client_id, client_secret, em_url, topic, data): """Publish event via Event Mesh REST API.""" # Get OAuth token token_resp = requests.post( f"{token_url}/oauth/token?grant_type=client_credentials", auth=(client_id, client_secret) ) token = token_resp.json()["access_token"] # Publish encoded_topic = topic.replace("/", "%2F") resp = requests.post( f"{em_url}/messagingrest/v1/topics/{encoded_topic}/messages", headers={ "Authorization": f"Bearer {token}", "Content-Type": "application/cloudevents+json", "x-qos": "1" # 0=at-most-once, 1=at-least-once }, json={ "specversion": "1.0", "type": topic, "source": "/custom/myapp", "id": str(__import__('uuid').uuid4()), "data": data } ) resp.raise_for_status() return resp.status_code ``` ### Pattern 4: Queue Subscription with Webhook ```python def create_queue_subscription(token, em_url, queue_name, topic_filter): """Create queue and bind topic subscription.""" headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} # Create queue requests.put( f"{em_url}/messagingrest/v1/queues/{queue_name}", headers=headers, json={"messageTimeToLive": 86400, "maxQueueSizeInBytes": 10485760} ) # Subscribe queue to topic encoded_topic = topic_filter.replace("/", "%2F") requests.put( f"{em_url}/messagingrest/v1/queues/{queue_name}/subscriptions/{encoded_topic}", headers=headers ) ``` ### Pattern 5: S/4HANA Business Event Configuration **Enable events in S/4HANA Cloud:** 1. App: "Enterprise Event Enablement" → Maintain channel binding 2. Create channel: type = "SAP Event Mesh", connection = destination to Event Mesh 3. Select event topics: `sap.s4.beh.salesorder.v1.SalesOrder.Created.v1` 4. Activate channel **S/4HANA On-Premise (via Integration Suite):** ``` S/4HANA → AIF/IDoc → SAP Integration Suite → Event Mesh ``` ### Pattern 6: Dead Letter Queue Pattern ```javascript // Handle failed messages with retry const msg = await cds.connect.to('messaging'); msg.on('custom/myapp/order/created/v1', async (event) => { try { await processOrder(event.data); } catch (err) { const retryCount = (event.headers['x-retry-count'] || 0) + 1; if (retryCount <= 3) { await msg.emit('custom/myapp/order/created/retry/v1', { ...event.data, _retryCount: retryCount, _originalError: err.message }); } else { await msg.emit('custom/myapp/dlq/order/v1', { ...event.data, _error: err.message, _failedAt: new Date().toISOString() }); } } }); ``` ## Error Catalog | Error | Message | Root Cause | Fix | |-------|---------|------------|-----| | `403` | Publish not allowed | Topic not in `publishFilter` | Update `event-mesh.json` rules | | `403` | Subscribe not allowed | Topic not in `subscribeFilter` | Update subscribe filter rules | | `404` | Queue not found | Queue deleted or not created | Create queue before consuming | | `409` | Queue already exists | Duplicate creation attempt | Use PUT (idempotent) instead of POST | | `413` | Message too large | Exceeds max message size (1 MB default) | Reduce payload; use reference pattern (send URL) | | `429` | Rate limit exceeded | Too many requests per second | Implement backoff; upgrade service plan | | `500` | Broker unavailable | Event Mesh service issue | Check BTP system status; retry with backoff | | Connection refused | AMQP connection failed | Wrong endpoint or credentials | Verify service key `messaging` array endpoints | | No messages | Consumer gets nothing | Topic filter mismatch | Check wildcard syntax; verify namespace prefix | | Duplicate events | Same event processed twice | At-least-once QoS | Implement idempotent consumer (check event ID) | ## Performance Tips 1. **Use QoS 0 for non-critical events** — At-most-once is faster; use QoS 1 only for business-critical events 2. **Batch publishing** — Group multiple events per HTTP request where API supports it 3. **Partition queues** — Use multiple queues for parallel consumption of high-volume topics 4. **Message TTL** — Set appropriate `messageTimeToLive` to prevent queue overflow 5. **Payload size** — Keep events small (<10 KB); reference large data via URL/ID 6. **AMQP over REST** — Use AMQP protocol for high-throughput; REST for low-volume/webhook 7. **Consumer acknowledgment** — Acknowledge messages promptly; long processing delays redelivery 8. **Namespace isolation** — Separate namespaces per application; avoid cross-app topic pollution ## Gotchas - **Topic encoding**: Forward slashes in topic names must be URL-encoded (`%2F`) in REST API paths - **Namespace prefix**: All topics must match namespace defined in service instance; mismatches silently fail - **Event ordering**: Event Mesh does NOT guarantee message ordering — design consumers to be order-independent - **Duplicate delivery**: At-least-once means duplicates are possible — always implement idempotent processing - **Service plan limits**: `default` plan has message size and throughput limits; check plan quotas - **S/4HANA events**: Business events must be explicitly enabled per tenant; they're not on by default
在 GitHub 查看