Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:55:10 +08:00
commit 3fdee31e08
14 changed files with 4296 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
{
"name": "sap-btp-job-scheduling",
"description": "Job Scheduling Service for one-time and recurring jobs on BTP. Covers REST API, cron schedules, OAuth 2.0, Cloud Foundry tasks, and Kyma integration.",
"version": "1.0.0",
"author": {
"name": "Zhongwei Li",
"email": "zhongweili@tubi.tv"
},
"skills": [
"./"
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# sap-btp-job-scheduling
Job Scheduling Service for one-time and recurring jobs on BTP. Covers REST API, cron schedules, OAuth 2.0, Cloud Foundry tasks, and Kyma integration.

401
SKILL.md Normal file
View File

@@ -0,0 +1,401 @@
---
name: sap-btp-job-scheduling
description: |
This skill provides comprehensive guidance for SAP BTP Job Scheduling Service development, configuration, and operations.
It should be used when creating, managing, or troubleshooting scheduled jobs on SAP Business Technology Platform.
The skill covers service setup, REST API usage, schedule types and formats, OAuth 2.0 authentication, multitenancy,
Cloud Foundry tasks, Kyma runtime integration, and monitoring with SAP Cloud ALM and Alert Notification Service.
Keywords: SAP BTP, Job Scheduling, jobscheduler, cron, schedule, recurring jobs, one-time jobs, Cloud Foundry tasks,
CF tasks, Kyma, OAuth 2.0, XSUAA, @sap/jobs-client, REST API, asynchronous jobs, action endpoint, run logs,
SAP Cloud ALM, Alert Notification Service, multitenancy, tenant-aware, BC-CP-CF-JBS
license: GPL-3.0
metadata:
version: "1.0.1"
last_verified: "2025-11-27"
---
# SAP BTP Job Scheduling Service
## Table of Contents
- [Overview](#overview)
- [When to Use This Skill](#when-to-use-this-skill)
- [Quick Decision Tree](#quick-decision-tree)
- [Core Concepts](#core-concepts)
- [Service Constraints](#service-constraints)
- [Quick Reference Tables](#quick-reference-tables)
- [Schedule Formats](#schedule-formats)
- [Cron Format (7 fields)](#cron-format-7-fields)
- [Schedule Lifecycle States](#schedule-lifecycle-states)
- [HTTP Methods for Jobs](#http-methods-for-jobs)
- [Best Practices](#best-practices)
- [Scheduling Optimization](#scheduling-optimization)
- [Asynchronous Jobs](#asynchronous-jobs)
- [One-Time Schedules](#one-time-schedules)
- [Authentication Quick Start](#authentication-quick-start)
- [Standard Plan (OAuth 2.0)](#standard-plan-oauth-20)
- [xs-security.json Configuration](#xs-securityjson-configuration)
- [Create Job Example](#create-job-example)
- [Node.js Client Library](#nodejs-client-library)
- [Rate Limits](#rate-limits)
- [Service Behavior](#service-behavior)
- [Outage Recovery](#outage-recovery)
- [Auto-Deactivation Triggers](#auto-deactivation-triggers)
- [Bundled Resources](#bundled-resources)
- [Common Pitfalls](#common-pitfalls)
- [External Resources](#external-resources)
- [Updates and Maintenance](#updates-and-maintenance)
## Overview
SAP Job Scheduling Service is a runtime-agnostic platform service for defining and managing one-time and recurring jobs or Cloud Foundry tasks on SAP BTP. It operates across multiple hyperscalers (AWS, Azure, GCP) without requiring application modifications.
**Documentation Source**: [https://help.sap.com/docs/job-scheduling](https://help.sap.com/docs/job-scheduling)
**Last Verified**: 2025-11-27
## When to Use This Skill
Use this skill when:
- **Setting up Job Scheduling Service** on Cloud Foundry or Kyma runtime
- **Creating and managing jobs** via REST API or dashboard
- **Configuring schedules** using cron, date/time, or human-readable formats
- **Implementing asynchronous job execution** for long-running processes
- **Securing action endpoints** with OAuth 2.0 and XSUAA
- **Integrating with SAP Cloud ALM** or Alert Notification Service
- **Developing multitenant applications** with tenant-aware job scheduling
- **Troubleshooting job execution issues** and schedule failures
- **Using the Node.js client library** (@sap/jobs-client)
## Quick Decision Tree
### What Task?
```
Setup & Configuration
├─ Initial setup prerequisites → references/setup-guide.md
├─ Create service instance
│ ├─ BTP Cockpit → references/setup-guide.md#cockpit
│ ├─ CF CLI → references/setup-guide.md#cf-cli
│ └─ Kyma Dashboard → references/setup-guide.md#kyma
└─ Configure XSUAA scopes → references/security.md
Job Management
├─ Create jobs → references/rest-api.md#create-job
├─ Configure schedules → references/rest-api.md#schedules
├─ Run logs & monitoring → references/rest-api.md#run-logs
└─ Dashboard operations → references/operations.md#dashboard
Schedule Configuration
├─ One-time vs recurring → references/concepts.md#schedule-types
├─ Cron format → references/concepts.md#cron-format
├─ Date/time formats → references/concepts.md#date-formats
└─ Human-readable → references/concepts.md#human-readable
Asynchronous Execution
├─ Async mode flow → references/concepts.md#async-mode
├─ Callback implementation → references/rest-api.md#update-run-log
└─ CF tasks → references/concepts.md#cf-tasks
Security & Authentication
├─ OAuth 2.0 setup → references/security.md#oauth
├─ XSUAA configuration → references/security.md#xsuaa
└─ Credential rotation → references/security.md#rotation
Integrations
├─ SAP Cloud ALM → references/integrations.md#cloud-alm
└─ Alert Notification → references/integrations.md#alert-notification
Troubleshooting
├─ Common errors → references/troubleshooting.md#errors
├─ FAQ → references/troubleshooting.md#faq
└─ Support: BC-CP-CF-JBS
Version History & Updates
└─ What's New (2021-2025) → references/changelog.md
```
## Core Concepts
### Job
A collection of schedules with an action endpoint. Jobs invoke a configured URL at specified times synchronously (short operations) or asynchronously (long processes).
### Schedule
A one-time or recurring entity within a job. Supports multiple formats (cron, date/time, human-readable) and has three lifecycle states: SCHEDULED → RUNNING → COMPLETED.
### Action Endpoint
An HTTP/REST endpoint exposed by your application that the service invokes when schedules trigger. Must be OAuth 2.0 protected in production.
### Cloud Foundry Task
An app or script that runs independently in its own container. Always executes asynchronously with configurable memory allocation.
## Service Constraints
| Constraint | Value |
|------------|-------|
| Minimum schedule interval | 5 minutes |
| Synchronous request timeout | 15 seconds |
| Asynchronous timeout (default) | 30 minutes (configurable up to 7 days) |
| POST request body limit | 100 KB |
| Run log retention | 15 days |
| Service SLA | ~20 minutes from scheduled time |
## Quick Reference Tables
### Schedule Formats
| Format | Example | Use Case |
|--------|---------|----------|
| Cron | `* * * * 10:12 0,30 0` | Every 30 min between 10:00-12:00 |
| Date/Time | `2025-10-20T04:30:00Z` | ISO-8601 one-time execution |
| Human-readable | `tomorrow at 4pm` | Natural language scheduling |
| repeatInterval | `2 hours`, `5 minutes` | Recurring at fixed intervals |
| repeatAt | `4.40pm`, `18:40` | Daily at specific time |
### Cron Format (7 fields)
```
Year Month Day DayOfWeek Hour Minute Second
* * * * * * *
```
| Field | Values | Special |
|-------|--------|---------|
| Year | 4-digit (2025) | * = any |
| Month | 1-12 | */a = every a-th |
| Day | -31 to 31 | negative = from end |
| DayOfWeek | mon, tue, wed... | a.y = a-th occurrence |
| Hour | 0-23 | a:b = range |
| Minute | 0-59 | a:b/c = step in range |
| Second | 0-59 | a,b,c = multiple values |
### Schedule Lifecycle States
| Phase | States | Description |
|-------|--------|-------------|
| SCHEDULED | SCHEDULED | Queued for future run |
| RUNNING | TRIGGERED, ACK_RECVD, ACK_NOT_RECVD | Executing |
| COMPLETED | SUCCESS, ERROR, REQUEST_ERROR, UNKNOWN | Finished |
### HTTP Methods for Jobs
| Method | Endpoint | Purpose |
|--------|----------|---------|
| POST | `/scheduler/jobs` | Create job |
| GET | `/scheduler/jobs` | List all jobs |
| GET | `/scheduler/jobs/{id}` | Get job details |
| PUT | `/scheduler/jobs/{id}` | Update job |
| DELETE | `/scheduler/jobs/{id}` | Delete job |
## Best Practices
### Scheduling Optimization
**Avoid Peak Times:**
- ❌ 0th or 30th second of any minute
- ❌ 0th, 30th, or multiples of 5 minutes
- ❌ Top of each hour
- ❌ Midnight UTC (busiest time)
**Use Irregular Times:**
-`01:12:17` instead of `01:00:00`
-`01:38:37` instead of `01:30:00`
### Asynchronous Jobs
1. **Return 202 Accepted immediately** - Don't block the request
2. **Store request headers** - `x-sap-job-id`, `x-sap-job-schedule-id`, `x-sap-job-run-id`, `x-sap-scheduler-host`
3. **Update run log on completion** - Single API call with final status
4. **Handle timeouts** - Default 30 min, configurable up to 7 days
### One-Time Schedules
- Use only for testing/validation
- Auto-deactivate after execution
- Use `"time": "now"` for immediate execution
## Authentication Quick Start
### Standard Plan (OAuth 2.0)
```bash
# Get access token
curl -X POST "<uaa_url>/oauth/token" \
-H "Authorization: Basic $(echo -n '<clientid>:<clientsecret>' | base64)" \
-d "grant_type=client_credentials"
# Use token in API calls
curl -X GET "[https://jobscheduler-rest.<landscape>/scheduler/jobs"](https://jobscheduler-rest.<landscape>/scheduler/jobs") \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json"
```
### xs-security.json Configuration
```json
{
"xsappname": "<app-name>",
"scopes": [{
"name": "$XSAPPNAME.JOBSCHEDULER",
"description": "Job Scheduler Scope",
"grant-as-authority-to-apps": ["$XSSERVICENAME(<jobscheduler-instance>)"]
}]
}
```
## Create Job Example
```json
POST /scheduler/jobs
{
"name": "myJob",
"description": "Process daily reports",
"action": "[https://myapp.cfapps.eu10.hana.ondemand.com/api/process",](https://myapp.cfapps.eu10.hana.ondemand.com/api/process",)
"active": true,
"httpMethod": "POST",
"schedules": [{
"active": true,
"description": "Daily at 6 AM",
"repeatAt": "6.00am",
"startTime": {"date": "2025-01-01", "format": "YYYY-MM-DD"}
}]
}
```
## Node.js Client Library
**Requirements**: Node.js 14.x or later
```bash
npm install @sap/jobs-client@1.8.6
```
```javascript
const JobSchedulerClient = require('@sap/jobs-client');
const scheduler = new JobSchedulerClient.Scheduler();
// Create job
scheduler.createJob({ url: vcapServices.jobscheduler[0].credentials.url }, {
name: 'myJob',
action: '[https://myapp.../process',](https://myapp.../process',)
active: true,
httpMethod: 'GET',
schedules: [{ cron: '* * * * 0 0 0', active: true }]
}, (err, result) => { /* handle */ });
```
## Rate Limits
| Limit Type | Response Code | Header |
|------------|---------------|--------|
| Client limit exceeded | 429 | `retry-after` (seconds) |
| Absolute limit exceeded | 503 | `throttling` (milliseconds) |
Limits stack - both can apply simultaneously.
## Service Behavior
### Outage Recovery
| Outage Duration | Behavior |
|-----------------|----------|
| < 20 minutes | All missed executions run immediately |
| >= 20 minutes | Only last missed execution runs |
### Auto-Deactivation Triggers
- One-time schedule executed
- No valid future dates exist
- Job/schedule endTime reached
- Action endpoint unreachable for 10+ days
## Reference Files
### Detailed Guides Available
1. **references/concepts.md** - Schedule types, formats, lifecycle, async mode, multitenancy
2. **references/rest-api.md** - Complete REST API reference with all endpoints
3. **references/setup-guide.md** - Prerequisites, service instance creation
4. **references/security.md** - OAuth 2.0, XSUAA scopes, credential rotation
5. **references/integrations.md** - Cloud ALM, Alert Notification Service
6. **references/troubleshooting.md** - FAQ, error scenarios, monitoring
7. **references/operations.md** - Dashboard, backup/restore, service behavior
8. **references/changelog.md** - Version history, feature updates (2021-2025)
### Templates Available
1. **templates/job-creation.json** - Job creation request template
2. **templates/xs-security.json** - XSUAA configuration template
## Common Pitfalls
**Setup:**
- ❌ Missing XSUAA binding before Job Scheduling binding
- ❌ Not granting scopes via `grant-as-authority-to-apps`
- ❌ Using HTTP instead of HTTPS for action endpoints
**Scheduling:**
- ❌ Using Linux cron format (service uses SAP cron)
- ❌ Scheduling at peak times (00:00, 00:30, etc.)
- ❌ Forgetting UTC timezone (only supported timezone)
**Async Jobs:**
- ❌ Not returning 202 Accepted immediately
- ❌ Forgetting to call Update Run Log API
- ❌ Multiple status updates instead of single final update
**Multitenancy:**
- ❌ Using `tenantId` filter with SaaS tenant tokens (returns 400)
- ❌ Missing Job Scheduling as application dependency
## External Resources
### SAP Documentation
- **SAP Help Portal**: [https://help.sap.com/docs/job-scheduling](https://help.sap.com/docs/job-scheduling)
- **SAP Developer Center**: [https://developers.sap.com/](https://developers.sap.com/)
### Support
- **Component**: BC-CP-CF-JBS
- **SAP Trust Center**: Platform status verification
- **Guided Answers**: Self-service troubleshooting
## Updates and Maintenance
**Source**: SAP BTP Job Scheduling Service Documentation
**To Update This Skill**:
1. Check GitHub repository for documentation updates
2. Review What's New section for changes
3. Update affected reference files
4. Update templates if configurations changed
5. Update "Last Verified" date
**Quarterly Review Recommended**: Check for updates every 3 months
**Next Review**: 2026-02-27
## Bundled Resources
### Reference Files
1. **references/concepts.md** - Schedule types, formats, lifecycle, async mode, multitenancy (12K lines)
2. **references/rest-api.md** - Complete REST API reference with all endpoints (20K lines)
3. **references/setup-guide.md** - Prerequisites, service instance creation (9K lines)
4. **references/security.md** - OAuth 2.0, XSUAA scopes, credential rotation (11K lines)
5. **references/integrations.md** - Cloud ALM, Alert Notification Service (8K lines)
6. **references/troubleshooting.md** - FAQ, error scenarios, monitoring (9K lines)
7. **references/operations.md** - Dashboard, backup/restore, service behavior (8K lines)
8. **references/changelog.md** - Version history, feature updates (2021-2025) (9K lines)
### Templates
1. **templates/job-creation.json** - Job creation request template with examples
2. **templates/xs-security.json** - XSUAA configuration template for OAuth scopes
---
**Skill Version**: 1.0.1
**Last Updated**: 2025-11-27
**License**: GPL-3.0
**Maintainer**: SAP Skills Team | [https://github.com/secondsky/sap-skills](https://github.com/secondsky/sap-skills)

85
plugin.lock.json Normal file
View File

@@ -0,0 +1,85 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:secondsky/sap-skills:skills/sap-btp-job-scheduling",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "aea73701fe9535444c4fac7d8ddbe3c83e5fbfd1",
"treeHash": "071d953e16ae40978f3dbe266ba74e045fc180ea28c94140c11abed04c32cdb2",
"generatedAt": "2025-11-28T10:28:13.034617Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "sap-btp-job-scheduling",
"description": "Job Scheduling Service for one-time and recurring jobs on BTP. Covers REST API, cron schedules, OAuth 2.0, Cloud Foundry tasks, and Kyma integration.",
"version": "1.0.0"
},
"content": {
"files": [
{
"path": "README.md",
"sha256": "e4d58e44164da505a109c360c63e084f85da892ea09590d0d48c8c1194b9a6a5"
},
{
"path": "SKILL.md",
"sha256": "3885d6d5de0f4e5ec722768676a61aef5d2066521b0334d382a3d9bbfca07b5e"
},
{
"path": "references/operations.md",
"sha256": "5bb8bddca2d75dc219fc7ae6e0e419d84d803763f35b5968758cf1f07470e268"
},
{
"path": "references/changelog.md",
"sha256": "d6b59703cdd645c51d4d0e189e8d6de8a73e60922f0da39233b2819bc11936a6"
},
{
"path": "references/troubleshooting.md",
"sha256": "1b155e3fbc362718f2e08c8b928f12d8a6cf72da7631e1afe295385e620584a8"
},
{
"path": "references/concepts.md",
"sha256": "a1bad502cca083832548b6bd5245f26423d2396561e59dadc2e5d48833d8416e"
},
{
"path": "references/integrations.md",
"sha256": "6eb9c93e86791bb6033f708da7b158ee892dd875894847c1c58fadf55fde2add"
},
{
"path": "references/setup-guide.md",
"sha256": "6c3d6d61ada193d5b6ee971346672c1e53fab640d393b57e7862faef2a97d48e"
},
{
"path": "references/security.md",
"sha256": "c360fd470aa3af1902c37040e20193fc7d202edd15a8bdd3f0e389011910bd05"
},
{
"path": "references/rest-api.md",
"sha256": "46fe690354998189a83f7a4110a7a3968b76191851de1549ec156c7b77170f80"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "d69022eaa1f9f46c86eac7f3f4c22e3ec94c73d3b24e261182a8d9a802938edc"
},
{
"path": "templates/job-creation.json",
"sha256": "02f61e6db91f9cc5e3e54457e65043fe8bc58e2ef94a3ac4462bb58e9745ffcb"
},
{
"path": "templates/xs-security.json",
"sha256": "4f7d37abdbc54bc44c7a9a6e084f0b64b9c847d0b49881077e1678fa75ba4a24"
}
],
"dirSha256": "071d953e16ae40978f3dbe266ba74e045fc180ea28c94140c11abed04c32cdb2"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}

400
references/changelog.md Normal file
View File

@@ -0,0 +1,400 @@
# SAP BTP Job Scheduling Service - Changelog & Version History
**Source**: [https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs/10---What-s-New](https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs/10---What-s-New)
**Last Updated**: 2025-11-22
---
## Table of Contents
1. [2025 Updates](#2025-updates)
2. [2024 Updates](#2024-updates)
3. [2023 Updates](#2023-updates)
4. [2022 Updates](#2022-updates)
5. [2021 Updates](#2021-updates)
6. [Feature Summary](#feature-summary)
---
## 2025 Updates
### August 21, 2025 - Belize Themes Removed
**Type:** Changed
**Description:** The older Belize UI themes were discontinued. Users now select from four Horizon options:
- Morning Horizon (Default)
- Evening Horizon
- Horizon High Contrast Black
- Horizon High Contrast White
**Impact:** Systems automatically migrated users from deprecated themes.
---
### July 24, 2025 - New Event Resource Tags
**Type:** New Feature
**Description:** Added three new resource tags for event matching with SAP Alert Notification Service:
- `runStatus`
- `runState`
- `scheduleDescription`
**Use Case:** Enhanced monitoring and filtering capabilities for job notifications.
---
### June 12, 2025 - Default Theme Changed
**Type:** Changed
**Description:** "Morning Horizon" became the standard UI theme, replacing the older Belize default.
---
### May 29, 2025 - Multiple Updates
**1. Horizon Themes Introduced**
**Type:** New Feature
**Description:** Four new theme options available for dashboard customization:
- Morning Horizon
- Evening Horizon
- Horizon High Contrast Black
- Horizon High Contrast White
---
**2. SAP Cloud ALM Integration**
**Type:** New Feature
**Description:** New capability enabling direct job status tracking through SAP Cloud ALM's interface.
**Configuration:**
```json
{
"calmConfig": {
"enabled": true
}
}
```
---
**3. One-Time Schedule Cleanup Policy**
**Type:** New Feature
**Description:** Unused one-time schedules are now automatically deleted after **30 days of inactivity**.
**Recommendation:** Use recurring schedules as alternative for persistent scheduling needs.
**Important:** This is an automatic cleanup - no action required, but be aware that inactive one-time schedules will be removed.
---
## 2024 Updates
### November 14, 2024 - Service Instance Creation Simplified
**Type:** Changed
**Description:** The `enable-xsuaa-support` property now **defaults to enabled**, eliminating manual configuration requirements.
**Impact:**
- New service instances automatically support XSUAA
- No additional parameters needed during creation
- Simplifies initial setup process
**Before (Required):**
```json
{
"enable-xsuaa-support": true
}
```
**After (Default behavior):** No parameter needed.
---
## 2023 Updates
### August 24, 2023 - Kyma Runtime Support
**Type:** New Feature
**Description:** Cross-consumption capabilities for Kyma runtime announced.
**Availability:** Public cloud infrastructure providers only (AWS, Azure, GCP).
**Environments Supported:**
- Cloud Foundry runtime
- Kyma runtime
---
### July 13, 2023 - Job Filtering in Dashboard
**Type:** New Feature
**Description:** Job filtering functionality introduced for the list view.
**Filter Options:**
- By job name
- By subdomain
- By tenant ID
---
### May 18, 2023 - Two Updates
**1. Service Key Creation**
**Type:** New Feature
**Description:** Service key creation capability added for the standard service plan.
**Use Case:** Enables credential generation for service instances without application binding.
**Command:**
```bash
cf create-service-key <instance-name> <key-name>
```
---
**2. SAP Alert Notification Integration**
**Type:** New Feature
**Description:** Integration with SAP Alert Notification service enabled.
**Capabilities:**
- Send notifications when jobs succeed
- Send notifications when jobs fail
- Configure via `ansConfig` in job creation
**Configuration:**
```json
{
"ansConfig": {
"onSuccess": true,
"onError": true
}
}
```
**Availability:** Cloud Foundry only (not Kyma).
---
### February 9, 2023 - Enhanced Table Column Management
**Type:** New Feature
**Description:** Enhanced table column management in the Service Dashboard.
**New Capabilities:**
- Adjust width of any column
- Menu options to view full job/task names
- Toggle between truncated and full-name display
---
## 2022 Updates
### September 23, 2022 - Asynchronous Timeout Limit
**Type:** Changed
**Description:** The Asynchronous Execution Timeout configuration parameter now has a maximum ceiling.
**Maximum Value:** 604,800 seconds (7 days)
**Configuration Location:** Service Dashboard → Configurations
---
### February 24, 2022 - REST API Rate Limiting
**Type:** New Feature
**Description:** API calls are now subject to rate limits that may delay or deny requests during high load periods.
**Response Codes:**
| Limit Type | Response Code | Header |
|------------|---------------|--------|
| Client limit | 429 | `retry-after` |
| Absolute limit | 503 | `throttling` |
**Recovery:** Denied requests can be retried after less than one minute.
---
### February 10, 2022 - Automatic Schedule Deactivation
**Type:** New Feature
**Description:** The system now automatically deactivates schedules under certain conditions.
**Deactivation Triggers:**
- One-time schedule executed
- No valid future dates exist
- Job/schedule endTime reached
- Action endpoint unreachable for 10+ consecutive days
---
### January 27, 2022 - Certificate-Based Service Binding
**Type:** New Feature
**Description:** Users can bind service instances using X.509 certificates.
**Recommendation:** SAP's recommended practice for secure connections.
**Configuration:**
```json
{
"credential-type": "x509",
"x509": {
"key-length": 2048,
"validity": 7,
"validity-type": "DAYS"
}
}
```
---
## 2021 Updates
### December 16, 2021 - Two Updates
**1. REST API Rate Limits**
**Type:** New Feature
**Description:** Implemented request rate limiting with retry header.
---
**2. Missed Run Behavior**
**Type:** New Feature
**Description:** Service now skips all missed executions except the last one during outages exceeding 20 minutes.
**Behavior:**
| Outage Duration | Behavior |
|-----------------|----------|
| < 20 minutes | All missed runs executed |
| >= 20 minutes | Only last missed run executed |
**Rationale:** Prevents overwhelming target applications upon recovery.
---
### May 20, 2021 - Custom Identity Provider Support
**Type:** New Feature
**Description:** The service extended compatibility to work with custom identity providers alongside platform users.
**Capabilities:**
- Dashboard management with custom IdP
- Support for federated authentication
---
### February 25, 2021 - CF Task Timeout
**Type:** New Feature
**Description:** Asynchronous job execution adopted a 30-minute default timeout limit.
**Details:**
- Tasks automatically terminated after timeout
- Configurable via Service Dashboard → Configurations
- Maximum: 604,800 seconds (7 days)
---
### December 17, 2020 - Binding Level Secrets
**Type:** New Feature
**Description:** New client secrets are automatically generated when applications bind to the service.
**Benefit:** Enables secret rotation through unbind/rebind cycles.
**Rotation Process:**
1. `cf unbind-service <app> <instance>`
2. `cf bind-service <app> <instance>`
3. `cf restage <app>`
---
## Feature Summary
### Key Capabilities by Year
| Year | Major Features |
|------|---------------|
| 2025 | Horizon themes, Cloud ALM integration, one-time schedule cleanup |
| 2024 | Simplified XSUAA setup (defaults enabled) |
| 2023 | Kyma support, Alert Notification, service keys, job filtering |
| 2022 | Rate limiting, certificate binding, auto-deactivation, async timeout cap |
| 2021 | Custom IdP, CF task timeout, missed run behavior, binding secrets |
### Current Feature Set
**Scheduling:**
- One-time and recurring schedules
- Cron, date/time, human-readable formats
- Automatic cleanup of unused one-time schedules (30 days)
**Execution:**
- Synchronous (≤15 seconds)
- Asynchronous (up to 7 days timeout)
- Cloud Foundry tasks
**Security:**
- OAuth 2.0 (XSUAA) - default enabled
- X.509 certificate binding (recommended)
- Custom identity provider support
- Binding-level credential rotation
**Monitoring:**
- SAP Cloud ALM integration
- SAP Alert Notification Service (CF only)
- Event resource tags (runStatus, runState, scheduleDescription)
**Management:**
- Service Dashboard with Horizon themes
- REST API with rate limiting
- Node.js client library
- Job filtering by name, subdomain, tenant ID
**Runtimes:**
- Cloud Foundry
- Kyma (public cloud only)
---
## External References
### SAP Documentation
- **What's New**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/what-s-new-for-sap-job-scheduling-service](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/what-s-new-for-sap-job-scheduling-service)
- **2023 Archive**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/2023-what-s-new-for-sap-job-scheduling-service-archive](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/2023-what-s-new-for-sap-job-scheduling-service-archive)
- **2022 Archive**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/2022-what-s-new-for-sap-job-scheduling-service-archive](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/2022-what-s-new-for-sap-job-scheduling-service-archive)
- **2021 Archive**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/2021-what-s-new-for-sap-job-scheduling-service-archive](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/2021-what-s-new-for-sap-job-scheduling-service-archive)
### Source Files
- `what-s-new-for-sap-job-scheduling-service-35dd2f8.md`
- `2023-what-s-new-for-sap-job-scheduling-service-archive-8ff6481.md`
- `2022-what-s-new-for-sap-job-scheduling-service-archive-cd1964a.md`
- `2021-what-s-new-for-sap-job-scheduling-service-archive-78f6a4b.md`

472
references/concepts.md Normal file
View File

@@ -0,0 +1,472 @@
# SAP BTP Job Scheduling Service - Core Concepts
**Source**: [https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs/20---Concepts](https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs/20---Concepts)
**Last Updated**: 2025-11-22
---
## Table of Contents
1. [Core Components](#core-components)
2. [Schedule Types](#schedule-types)
3. [Schedule Formats](#schedule-formats)
4. [Schedule Lifecycle](#schedule-lifecycle)
5. [Asynchronous Mode](#asynchronous-mode)
6. [Cloud Foundry Tasks](#cloud-foundry-tasks)
7. [Multitenancy](#multitenancy)
8. [Service Behavior](#service-behavior)
---
## Core Components
### Job
A job is a collection of schedules with an action endpoint. Jobs:
- Invoke a configured URL at specified times
- Execute synchronously (short operations, ≤15 seconds) or asynchronously (long processes)
- Service plans are based on the number of schedules within a job
- Names must not contain special characters or only numbers
- Names must be unique per technical user
### Action Endpoint
An HTTP or REST endpoint exposed by the application that the service invokes:
- Must be OAuth 2.0 protected in production (standard plan)
- Must use HTTPS for encrypted communication
- Receives job execution requests with authorization headers
### Schedule
A one-time or recurring entity within a job:
- Defines when and how often a job runs
- Supports multiple format types (cron, date/time, human-readable)
- Has its own lifecycle states
- Can be activated/deactivated independently
### Run Log
Records of job executions:
- Contains execution status, timestamps, and optional messages
- Retained for 15 days before automatic deletion
- Downloadable via API or dashboard
---
## Schedule Types
### One-Time Schedules
Execute a single time using:
**Human-Readable Text:**
```
"time": "10 hours from now"
"time": "tomorrow at 4pm"
"time": "now" // Immediate execution
"time": "Friday at 2am"
```
**Date String Formats:**
```
"time": "1994-11-05T08:15:30-05:00" // ISO-8601
"time": "Sat, 05 Nov 1994 08:15:30 GMT" // RFC 2822
```
**Behavior:**
- Auto-deactivate after execution (successful or failed)
- Execute at configured time, overriding job-level startTime
- Execute immediately if scheduled time is past but endTime is future
- Do not execute if both time and endTime are in the past
- **Automatic Cleanup:** Unused one-time schedules are deleted after **30 days of inactivity** (as of May 2025)
### Recurring Schedules
Run periodically at specified intervals using:
**repeatInterval:**
Denotes interval between schedules in human-readable format:
```json
"repeatInterval": "5 minutes"
"repeatInterval": "2 hours"
"repeatInterval": "1 day"
"repeatInterval": "2 weeks"
```
- Next execution adjusts if previous execution was delayed
**cron:**
Crontab expression determining execution times:
```json
"cron": "* * * * 9 0 0" // Daily at 9:00:00 AM
"cron": "* * * mon 10 0 0" // Every Monday at 10:00
```
- Service assumes 30-day months and 365-day years
**repeatAt:**
Exact daily execution time:
```json
"repeatAt": "4.40pm"
"repeatAt": "18.40"
"repeatAt": "6.20am"
```
**Behavior:**
- If a job exceeds its duration, the next scheduled job still starts on time
- Activating an inactive schedule after planned start triggers immediate execution
---
## Schedule Formats
### Cron Format (7 Fields)
SAP Job Scheduling Service uses an extended cron format with seven fields (left to right):
```
Year Month Day DayOfWeek Hour Minute Second
```
**Field Constraints:**
| Field | Values | Description |
|-------|--------|-------------|
| Year | 4-digit (e.g., 2025) | Calendar year |
| Month | 1-12 | Calendar month |
| Day | -31 to 31 | Day of month (negative = from end) |
| DayOfWeek | mon, tue, wed, thu, fri, sat, sun | 3-letter abbreviation |
| Hour | 0-23 | Hour of day |
| Minute | 0-59 | Minute of hour |
| Second | 0-59 | Second of minute |
**Supported Operators:**
| Operator | Meaning | Example |
|----------|---------|---------|
| `*` | Any value | `* * * * 9 0 0` |
| `*/a` | Every a-th value | `* * * * */2 0 0` (every 2 hours) |
| `a:b` | Range a to b | `* * * * 10:12 0 0` (hours 10-12) |
| `a:b/c` | Every c-th in range | `* * * * 10:12/2 0 0` |
| `a.y` | a-th occurrence of weekday y | `* * * -1.sun 9 0 0` (last Sunday) |
| `a,b,c` | Multiple values | `* * * mon,wed,fri 9 0 0` |
**Examples:**
```
* * * 10:12 */30 0 Every 30 minutes between 10:00-12:00 daily
* * * -1.sun 9 0 0 Last Sunday of each month at 09:00
* 1,4,7,10 1 * 0 0 0 First day of each quarter at midnight
* * * * 9 30 0 Daily at 9:30 AM
* * 15 * 18 0 0 15th of each month at 6 PM
```
**Important**: Service uses SAP cron format, NOT Linux cron format.
### Date/Time Formats
**Date Object Format:**
```json
{
"startTime": {
"date": "2025-10-20 04:30 +0000",
"format": "YYYY-MM-DD HH:mm Z"
}
}
```
**Supported Parsing Tokens:**
| Token | Description |
|-------|-------------|
| YYYY | 4-digit year |
| YY | 2-digit year |
| M/MM | Month (1-12) |
| MMM/MMMM | Month name |
| D/DD | Day of month |
| H/HH | Hour (24-hour) |
| h/hh | Hour (12-hour) |
| a/A | AM/PM |
| m/mm | Minute |
| s/ss | Second |
| Z/ZZ | Timezone offset |
| X | UNIX timestamp (seconds) |
| x | UNIX timestamp (milliseconds) |
**Date String Format:**
Valid ISO-8601 or RFC 2822 representations:
```
1994-11-05T08:15:30-05:00 // ISO-8601
Sat, 05 Nov 1994 08:15:30 GMT // RFC 2822
```
### Human-Readable Formats
**time Parameter:**
```
"10 hours from now"
"tomorrow at 4pm"
"now"
"Friday at 2am"
"next week"
```
**repeatAt Parameter:**
```
"4.40pm"
"6.20am"
"18:40"
```
**repeatInterval Parameter:**
```
"10 hours"
"2 days"
"5 minutes"
"3 weeks"
"1 month"
```
Supports: years, months, weeks, days, hours, minutes, seconds
---
## Schedule Lifecycle
### Primary States
| State | Description |
|-------|-------------|
| **SCHEDULED** | Schedule queued for future run |
| **RUNNING** | Schedule actively executing |
| **COMPLETED** | Schedule run finished |
### Detailed State Transitions
**During SCHEDULED Phase:**
- `SCHEDULED`: Awaiting execution at future time
**During RUNNING Phase:**
- `TRIGGERED`: Scheduler triggered request to job action endpoint
- `ACK_RECVD`: Application sent 202 Accepted acknowledgment
- `ACK_NOT_RECVD`: Application failed to acknowledge within timeframe
**During COMPLETED Phase:**
- `SUCCESS`: Application executed job and replied with success status
- `ERROR`: Application encountered error, sent server error code
- `REQUEST_ERROR`: Error occurred invoking job endpoint
- `UNKNOWN`: Application didn't invoke Update Job Run Log API
### Cloud Foundry Task States
**RUNNING Phase:**
- `TRIGGERED`: Task creation initiated
- `ACK_RECVD`: Task creation successful
**COMPLETED Phase:**
- `SUCCESS`: Task completed successfully
- `ERROR`: Task encountered error
- `TIMEOUT`: Execution exceeded configured timeframe
---
## Asynchronous Mode
### Overview
Asynchronous mode handles job runs with large execution times, particularly for action endpoints triggering long-running processes.
### Request Flow
1. **Scheduler Invokes Endpoint** with headers:
- `x-sap-job-id`: Job identifier
- `x-sap-job-schedule-id`: Schedule identifier
- `x-sap-job-run-id`: Run identifier
- `x-sap-scheduler-host`: Service host URI
2. **Application Stores Headers** using suitable mechanism (in-memory or persistent storage)
3. **Application Returns 202 Accepted** immediately as acknowledgment
4. **Application Processes Job** asynchronously
5. **Application Updates Run Log** via callback API with final status
### Implementation Example
```javascript
// Receive job request
app.post('/api/process', (req, res) => {
// Extract and store headers
const jobContext = {
jobId: req.headers['x-sap-job-id'],
scheduleId: req.headers['x-sap-job-schedule-id'],
runId: req.headers['x-sap-job-run-id'],
schedulerHost: req.headers['x-sap-scheduler-host']
};
// Store context for later callback
storeJobContext(jobContext);
// Return immediate acknowledgment
res.status(202).send({ message: 'Accepted' });
// Start async processing
processJobAsync(jobContext);
});
// After job completion
async function onJobComplete(jobContext, success, message) {
await updateRunLog(jobContext, { success, message });
}
```
### Callback API
```
PUT /scheduler/jobs/{jobId}/schedules/{scheduleId}/runs/{runId}
{
"success": true,
"message": "Long running operation completed successfully"
}
```
### Timeout Handling
- Default timeout: 30 minutes
- Configurable up to: 604,800 seconds (7 days)
- If application fails to invoke Update API, status reverts to `UNKNOWN`
### Important Notes
- Cloud Foundry tasks always run asynchronously
- Server error codes indicate job failure
- Single callback with final status (not multiple updates)
---
## Cloud Foundry Tasks
### Definition
An app or script whose code is included as part of a deployed app but runs independently in its own container.
### Characteristics
- Designed for minimal resource consumption
- Always execute asynchronously
- Cannot be created via REST API (only dashboard)
- Require Space Developer role for creation
- Memory configurable (default 1GB)
### Memory Configuration
Via dashboard JSON options:
```json
{
"memory_in_mb": 2048
}
```
### Task States
Same as asynchronous jobs plus:
- `TIMEOUT`: Execution exceeded configured timeframe
---
## Multitenancy
### Overview
The service enables deployed multitenant applications to create, view, edit, and delete jobs in the context of subscribed tenants.
### Prerequisites
- Application deployed to provider subaccount
- Application bound to SaaS Provisioning service
- Application bound to Job Scheduling service
- Job Scheduling defined as application dependency
### Tenant Isolation
**Strict Data Separation:**
- Jobs and schedules created for a SaaS tenant are NOT accessible by other tenants
- Credentials bound to a SaaS tenant access only that tenant's data
- Each tenant maintains its own job and schedule collection
### Credential Types
**Provider-Level Credentials (PaaS):**
- Bound to the SAP Job Scheduling service instance
- Can manage ALL jobs across all tenants
- No tenant restrictions
**Tenant-Specific Credentials (SaaS):**
- Bound to specific tenant
- Access only tenant-specific data
- `tenantId` query parameter returns 400 for SaaS tenant tokens
### Unsubscription Behavior
**Single-Instance Setup:**
- All corresponding jobs and schedules deleted when tenant unsubscribes
**Multi-Application Setup:**
- Data persists until ALL subscriptions removed
### Token Requirements
Use client credentials flow with XSUAA to obtain access tokens for job registration and management.
---
## Service Behavior
### Outage Recovery
**Under 20 Minutes:**
- All missed executions re-executed immediately when service restores
**20+ Minutes:**
- All scheduled runs except the last one are skipped
- Prevents overwhelming target applications with excessive requests
### Service Level Agreement
Scheduled jobs have approximately 20-minute latency tolerance from their scheduled execution time.
### Data Retention
Run logs automatically removed 15 days after generation. Download via API or dashboard before removal.
### Auto-Deactivation Triggers
Schedules auto-deactivate when:
- One-time schedule executed (successful or failed)
- No valid future dates exist
- Job/schedule endTime reached
- Action endpoint unreachable for 10+ consecutive days
### Timezone
**UTC Only**: No other timezones supported. All schedule times are interpreted as UTC.
---
## External References
### SAP Documentation
- **Core Concepts**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/concepts](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/concepts)
- **Schedule Formats**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/schedule-formats](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/schedule-formats)
- **Service Behavior**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/service-behavior](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/service-behavior)
### Source Files
- `concepts-26572ad.md`
- `asynchronous-mode-d9fd81c.md`
- `schedule-types-9cf8c14.md`
- `schedule-formats-54615f0.md`
- `schedule-lifecycle-e1805f2.md`
- `multitenancy-in-sap-job-scheduling-service-464b613.md`
- `service-behavior-d09664b.md`

310
references/integrations.md Normal file
View File

@@ -0,0 +1,310 @@
# SAP BTP Job Scheduling Service - Integration Guide
**Source**: [https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs](https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs)
**Last Updated**: 2025-11-22
---
## Table of Contents
1. [Integration Overview](#integration-overview)
2. [SAP Cloud ALM Integration](#sap-cloud-alm-integration)
3. [SAP Alert Notification Service Integration](#sap-alert-notification-service-integration)
---
## Integration Overview
SAP Job Scheduling Service integrates with two SAP solutions:
| Integration | Purpose | Availability |
|-------------|---------|--------------|
| SAP Cloud ALM | Job monitoring and automation | Cloud Foundry & Kyma |
| SAP Alert Notification Service | Event notifications | Cloud Foundry only |
---
## SAP Cloud ALM Integration
### Overview
Integration enables monitoring of jobs managed by SAP Job Scheduling service within SAP Cloud ALM. Once activated, all events related to a job and its schedules are visible within SAP Cloud ALM.
### Prerequisites
1. SAP Cloud ALM instance configured
2. Job & Automation Monitoring enabled
3. Refer to [SAP Cloud ALM Job Monitoring Setup](https://support.sap.com/en/alm/sap-cloud-alm/operations/expert-portal/job-monitoring/job-automation-monitoring-details.html)
### Enable via Dashboard
**Method 1: Actions Column Toggle**
1. Open Job Scheduling service dashboard
2. Navigate to **Jobs** or **Tasks**
3. Find the job in the list
4. Toggle the Cloud ALM switch in the Actions column
5. Save changes
**Method 2: During Job/Task Creation**
1. Create new job or task
2. Enable Cloud ALM monitoring in creation form
3. Complete job creation
**Method 3: Edit View**
1. Select existing job
2. Click **Edit**
3. Enable Cloud ALM monitoring toggle
4. Save changes
### Enable via REST API
**During Job Creation:**
```json
POST /scheduler/jobs
{
"name": "monitoredJob",
"description": "Job with Cloud ALM monitoring",
"action": "[https://myapp.../api/process",](https://myapp.../api/process",)
"active": true,
"httpMethod": "POST",
"calmConfig": {
"enabled": true
},
"schedules": [{
"active": true,
"repeatInterval": "1 hour"
}]
}
```
**Update Existing Job:**
```json
PUT /scheduler/jobs/{jobId}
{
"calmConfig": {
"enabled": true
}
}
```
### Configuration Notes
- CF tasks cannot be created via REST API due to application-specific binding
- `calmConfig` object cannot be empty if provided
- `enabled` must be boolean type
### Status Display Comparison
| Job Scheduling Display | Cloud ALM Display |
|------------------------|-------------------|
| Status + State (single column) | Execution Status + Application Status (separate) |
### Status Mapping
| Job Scheduling | Cloud ALM Execution Status | Cloud ALM Application Status |
|----------------|---------------------------|------------------------------|
| SCHEDULED | Scheduled | - |
| TRIGGERED | Running | - |
| SUCCESS | Completed | Success |
| ERROR | Completed | Error |
| UNKNOWN | Unknown | Unknown |
---
## SAP Alert Notification Service Integration
### Overview
Integration allows jobs and tasks to trigger event notifications through SAP Alert Notification service upon completion, supporting both success and error scenarios.
### Benefits
| Benefit | Description |
|---------|-------------|
| Proactive Monitoring | Immediate alerts for job outcomes |
| Operational Efficiency | Automatic recovery process initiation |
| Team Notification | Alert relevant stakeholders |
| Status Tracking | Track success, errors, timeouts, failures |
### Availability
**Supported:** Cloud Foundry runtime only
**Not Supported:** Kyma runtime
### Prerequisites
1. SAP Alert Notification service enabled in subaccount
2. Alert Notification service instance created
3. Event types configured:
- `JobSchedulerJobExecution`
- `JobSchedulerTaskExecution`
### Setup Steps
**Step 1: Create Alert Notification Instance**
1. Navigate to **Services****Instances and Subscriptions**
2. Create new **Alert Notification** service instance
3. Open service instance dashboard
**Step 2: Configure Actions**
1. In Alert Notification dashboard, go to **Actions**
2. Create action (e.g., Email, Webhook)
3. Configure action parameters
**Step 3: Configure Conditions**
1. Go to **Conditions**
2. Create condition for job events
3. Set event type filter:
- `JobSchedulerJobExecution` for jobs
- `JobSchedulerTaskExecution` for CF tasks
**Step 4: Configure Subscriptions**
1. Go to **Subscriptions**
2. Create subscription linking condition to action
3. Activate subscription
### Enable via Dashboard
**During Job Creation:**
1. Create new job in Job Scheduling dashboard
2. Under **SAP Alert Notification Service Events**:
- Toggle **Success** for success notifications
- Toggle **Error** for error notifications
3. Save job
**For Existing Jobs:**
1. Select job in dashboard
2. Click **Edit**
3. Enable notification toggles
4. Save changes
### Enable via REST API
**During Job Creation:**
```json
POST /scheduler/jobs
{
"name": "alertedJob",
"description": "Job with alert notifications",
"action": "[https://myapp.../api/process",](https://myapp.../api/process",)
"active": true,
"httpMethod": "POST",
"ansConfig": {
"onSuccess": true,
"onError": true
},
"schedules": [{
"active": true,
"cron": "* * * * 9 0 0"
}]
}
```
**Update Existing Job:**
```json
PUT /scheduler/jobs/{jobId}
{
"ansConfig": {
"onSuccess": false,
"onError": true
}
}
```
### ansConfig Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| onSuccess | boolean | Send notification on successful execution |
| onError | boolean | Send notification on failed execution |
### Event Types
| Event Type | Triggered By |
|------------|--------------|
| `JobSchedulerJobExecution` | HTTP endpoint job completion |
| `JobSchedulerTaskExecution` | Cloud Foundry task completion |
### Alert Events Include
- Job name and ID
- Schedule ID
- Execution status (Success/Error)
- Timestamp
- Error details (for failures)
### Testing Integration
1. Open Job Scheduling dashboard
2. Select **Jobs**
3. Create test job with:
- All required fields
- **Error** or **Success** toggle enabled
- One-time schedule with `"time": "now"`
4. Save and execute job
5. Verify:
- Job execution in run logs
- Notification received via configured action
### Troubleshooting
| Issue | Cause | Solution |
|-------|-------|----------|
| No notifications | Event type not configured | Add event types in ANS dashboard |
| Wrong recipients | Action misconfigured | Review action configuration |
| Delayed notifications | ANS processing time | Normal, check ANS logs |
| Missing events | ansConfig not set | Update job with ansConfig |
---
## Integration Configuration Summary
### REST API Parameters
| Integration | Parameter | Structure |
|-------------|-----------|-----------|
| SAP Cloud ALM | `calmConfig` | `{ "enabled": boolean }` |
| Alert Notification | `ansConfig` | `{ "onSuccess": boolean, "onError": boolean }` |
### Dashboard Options
| Integration | Location | Options |
|-------------|----------|---------|
| SAP Cloud ALM | Actions column / Edit view | Toggle on/off |
| Alert Notification | SAP Alert Notification Service Events | Success toggle, Error toggle |
### Compatibility Matrix
| Feature | Cloud Foundry | Kyma |
|---------|---------------|------|
| SAP Cloud ALM | Yes | Yes |
| Alert Notification | Yes | No |
---
## External References
### SAP Documentation
- **Integration Scenarios**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/integration-scenarios](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/integration-scenarios)
- **SAP Cloud ALM Integration**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/integration-with-sap-cloud-alm](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/integration-with-sap-cloud-alm)
- **Alert Notification Integration**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/integration-with-sap-alert-notification-service-for-sap-btp](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/integration-with-sap-alert-notification-service-for-sap-btp)
- **SAP Cloud ALM Job Monitoring**: [https://support.sap.com/en/alm/sap-cloud-alm/operations/expert-portal/job-monitoring/job-automation-monitoring-details.html](https://support.sap.com/en/alm/sap-cloud-alm/operations/expert-portal/job-monitoring/job-automation-monitoring-details.html)
### Source Files
- `integration-scenarios-faeec3a.md`
- `integration-with-sap-cloud-alm-f82790e.md`
- `integration-with-sap-alert-notification-service-for-sap-btp-972ef35.md`

321
references/operations.md Normal file
View File

@@ -0,0 +1,321 @@
# SAP BTP Job Scheduling Service - Operations Guide
**Source**: [https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs](https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs)
**Last Updated**: 2025-11-22
---
## Table of Contents
1. [Service Dashboard](#service-dashboard)
2. [Service Behavior](#service-behavior)
3. [Backup and Restore](#backup-and-restore)
4. [Accessibility Features](#accessibility-features)
---
## Service Dashboard
### Overview
The dashboard enables management of jobs, tasks, and schedules for a service instance.
### Access Methods
**Via SAP BTP Cockpit:**
1. Navigate to subaccount
2. Go to **Services****Instances and Subscriptions**
3. Select Job Scheduling instance
4. Click **View Dashboard** (via Service Bindings)
**Via CF CLI:**
```bash
cf service <service-instance-name>
```
Dashboard URL appears in output.
### Required Roles
| Runtime | Role | Access Level |
|---------|------|--------------|
| Cloud Foundry | SpaceDeveloper | Full access |
| Cloud Foundry | SpaceAuditor/SpaceManager/OrgManager/SpaceSupporter | Read-only |
| Kyma | SAP_Job_Scheduling_Service_Admin | Full access |
| Kyma | SAP_Job_Scheduling_Service_Viewer | Read-only |
### Dashboard Features
#### Configuration Management
| Setting | Description | Max Value |
|---------|-------------|-----------|
| Async Timeout | Timeout for async job execution | 604,800 seconds (7 days) |
#### Job Operations
| Operation | Description |
|-----------|-------------|
| Create | Create new job with action endpoint |
| Edit | Modify job properties |
| Deactivate | Disable job execution |
| Delete | Remove job and all data |
| Search | Filter by name, subdomain, tenant ID |
| Cloud ALM | Enable/disable monitoring |
#### Task Operations
| Operation | Description |
|-----------|-------------|
| Create | Create new CF task |
| Edit | Modify task properties |
| Memory | Configure task memory (JSON options) |
| Alert Notification | Enable/disable alerts (CF only) |
#### Schedule Operations
| Operation | Description |
|-----------|-------------|
| Create | Add schedule to job/task |
| Edit | Modify schedule parameters |
| Activate/Deactivate | Enable/disable schedule |
| Delete | Remove schedule |
| View History | See execution history |
| View Run Logs | See detailed execution logs |
### Dashboard UI Elements
**Main Sections:**
- Configurations panel
- Jobs/Tasks listing
- Schedule creation interface
- Event history viewer
- Run logs display
**Column Features:**
- Sortable (ascending/descending)
- Resizable widths
- Job name navigation
- Full-name display option
### Downloading Run Logs
1. Select job in dashboard
2. Choose specific schedule
3. View run logs
4. Click download option
**Note:** Logs auto-delete after 15 days.
---
## Service Behavior
### Execution Timing
#### Service Level Agreement
Scheduled jobs have approximately **20-minute tolerance** from their scheduled execution time.
#### Outage Recovery
| Outage Duration | Behavior |
|-----------------|----------|
| < 20 minutes | All missed executions run immediately |
| >= 20 minutes | Only last missed execution runs |
**Rationale:** Prevents overwhelming target applications with excessive requests upon recovery.
### Schedule Auto-Deactivation
Schedules automatically deactivate when:
| Trigger | Description |
|---------|-------------|
| One-time executed | After successful or failed execution |
| No future dates | All possible execution times passed |
| endTime reached | Job or schedule end time in past |
| Endpoint unreachable | Action endpoint unreachable 10+ consecutive days |
### Request Handling
| Constraint | Value |
|------------|-------|
| POST body limit | 100 KB |
| 413 response | Body size exceeded |
| Timezone | UTC only |
| Pagination default | 10 items |
| Pagination max | 200 items |
### Data Retention
| Data Type | Retention | Notes |
|-----------|-----------|-------|
| Run logs | 15 days | Auto-deleted |
| Jobs/Schedules | Indefinite | Until deleted |
| Configurations | Indefinite | Until instance deleted |
---
## Backup and Restore
### Capabilities
The service supports restoration of accidentally deleted items:
| Restorable | Not Restorable |
|------------|----------------|
| Job configurations | Run logs |
| Task configurations | Same-day deletions |
| Schedule configurations | - |
### Restored Item State
| Property | Restored Value |
|----------|----------------|
| active | `false` (requires manual reactivation) |
| All other settings | Original values |
### Restoration Time Windows
| Region | Maximum Window |
|--------|----------------|
| AWS | 14 days |
| Azure | 14 days |
| GCP | 7 days |
### Same-Day Limitation
**Jobs and schedules created, modified, or deleted on the same day cannot be restored** due to daily backup dependency.
### Restoration Procedures
#### For Deleted Service Instances
Submit SAP support case with:
- Tenant ID of subaccount
- Deletion timestamp
- Old instance GUID (from Space Events audit logs)
- New empty instance GUID for recovery
#### For Deleted Subscriptions
Submit SAP support case with:
- Tenant ID
- Deletion timestamp
- Provider instance GUID
Then:
1. Create new subscription
2. Wait for restoration completion
### Getting Instance GUID
**Via CF CLI:**
```bash
cf service <instance-name> --guid
```
**Via Audit Logs:**
1. Access Cloud Foundry audit logs
2. Filter for Space Events
3. Find DELETE event for service instance
4. Extract instance GUID from event details
---
## Accessibility Features
### UI Themes
The service offers four theme options:
| Theme | Description |
|-------|-------------|
| Morning Horizon | Default light theme |
| Evening Horizon | Dark theme |
| Horizon High Contrast Black | Accessibility - high contrast dark |
| Horizon High Contrast White | Accessibility - high contrast light |
### Changing Theme
1. Select email/profile in upper right corner
2. Choose **Change Theme**
3. Select preferred theme
### Screen Reader Support
Available through SAPUI5 accessibility framework:
- Screen reader compatibility
- Keyboard navigation options
- ARIA labels and roles
### BTP Cockpit Accessibility
Job Scheduling Service inherits accessibility features from SAP BTP cockpit:
- Keyboard shortcuts
- Focus management
- High contrast modes
### Documentation Resources
- SAP BTP Cockpit accessibility features (SAP Help Portal)
- SAPUI5 accessibility guidance for end users
---
## Operational Best Practices
### Scheduling
| Practice | Recommendation |
|----------|----------------|
| Avoid peak seconds | Don't use 0 or 30 |
| Avoid peak minutes | Don't use 0, 30, or multiples of 5 |
| Avoid top of hour | High demand periods |
| Avoid midnight UTC | Busiest time |
| Use irregular times | e.g., 01:12:17 vs 01:00:00 |
### Monitoring
| Approach | Method |
|----------|--------|
| Dashboard | Manual review of run logs |
| Cloud ALM | Automated monitoring |
| Alert Notification | Event-driven alerts |
| REST API | Programmatic log retrieval |
### Maintenance
| Task | Frequency |
|------|-----------|
| Download critical logs | Before 15-day retention |
| Review failed jobs | Daily/Weekly |
| Credential rotation | Quarterly |
| Verify scope grants | After XSUAA changes |
### Capacity Planning
| Factor | Consideration |
|--------|---------------|
| Schedule count | Service plan based on schedules |
| Execution frequency | Rate limits apply |
| Run log volume | 15-day auto-deletion |
| Memory (CF tasks) | Default 1GB, configurable |
---
## External References
### SAP Documentation
- **Dashboard**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/manage-jobs-tasks-and-schedules-with-service-dashboard](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/manage-jobs-tasks-and-schedules-with-service-dashboard)
- **Service Behavior**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/service-behavior](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/service-behavior)
- **Backup and Restore**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/backup-and-restore](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/backup-and-restore)
- **Accessibility**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/accessibility-features-in-sap-job-scheduling-service](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/accessibility-features-in-sap-job-scheduling-service)
### Source Files
- `manage-jobs-tasks-and-schedules-with-service-dashboard-132fd06.md`
- `service-behavior-d09664b.md`
- `backup-and-restore-87102ab.md`
- `accessibility-features-in-sap-job-scheduling-service-12aa90f.md`
- `best-practices-7b3f014.md`

937
references/rest-api.md Normal file
View File

@@ -0,0 +1,937 @@
# SAP BTP Job Scheduling Service - REST API Reference
**Source**: [https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs/40---Using-JOB-SCHDULR-TITLE](https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs/40---Using-JOB-SCHDULR-TITLE)
**Last Updated**: 2025-11-22
---
## Table of Contents
1. [API Overview](#api-overview)
2. [Authentication](#authentication)
3. [Rate Limits](#rate-limits)
4. [Job APIs](#job-apis)
5. [Schedule APIs](#schedule-apis)
6. [Run Log APIs](#run-log-apis)
7. [Node.js Client Library](#nodejs-client-library)
8. [Java Client Library (XS Advanced)](#java-client-library-xs-advanced)
---
## API Overview
### Base URL
```
[https://jobscheduler-rest.<landscape-domain>](https://jobscheduler-rest.<landscape-domain>)
```
Example landscapes:
- `eu10.hana.ondemand.com`
- `us10.hana.ondemand.com`
- `ap10.hana.ondemand.com`
### General Constraints
| Constraint | Value |
|------------|-------|
| Request body size limit | 100 KB |
| Content-Type | `application/json` |
| Timezone | UTC only |
| Pagination default | 10 items |
| Maximum pagination | 200 items |
### Request Headers
```
Authorization: Bearer <access_token>
Content-Type: application/json
```
---
## Authentication
### Lite Plan (HTTP Basic)
```bash
curl -X GET "[https://jobscheduler-rest.<domain>/scheduler/jobs"](https://jobscheduler-rest.<domain>/scheduler/jobs") \
-u "<user>:<password>" \
-H "Content-Type: application/json"
```
Credentials from `VCAP_SERVICES`:
- `user`: Username
- `password`: Password
### Standard Plan (OAuth 2.0)
**Token Acquisition - Client Credentials:**
```bash
# Get access token
curl -X POST "<credentials.uaa.url>/oauth/token" \
-H "Authorization: Basic $(echo -n '<clientid>:<clientsecret>' | base64)" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials"
```
Response:
```json
{
"access_token": "eyJhbGciOiJSUzI1...",
"token_type": "bearer",
"expires_in": 43199
}
```
**Token Acquisition - Certificate-Based:**
```bash
curl -X POST "<certurl>/oauth/token" \
--cert /path/to/certificate.pem \
--key /path/to/key.pem \
-d "grant_type=client_credentials&client_id=<clientid>"
```
**Using Token:**
```bash
curl -X GET "[https://jobscheduler-rest.<domain>/scheduler/jobs"](https://jobscheduler-rest.<domain>/scheduler/jobs") \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json"
```
### Credential Types
| Type | Authentication | Source |
|------|----------------|--------|
| binding-secret | clientid + clientsecret | VCAP_SERVICES |
| x509 | certificate + key | VCAP_SERVICES |
### Token Caching
Tokens cached up to 12 hours. Scope changes may take time to propagate.
---
## Rate Limits
### Limit Types
| Limit | Response | Header |
|-------|----------|--------|
| Client limit | 429 Too Many Requests | `retry-after` (seconds) |
| Absolute limit | 503 Service Unavailable | `throttling` (milliseconds) |
### Throttling Behavior
- When limits approached: Response delayed, `throttling` header indicates delay
- When client limit exceeded: 429 response with `retry-after`
- When absolute limit exceeded: 503 response
### Recovery
- Both limits stack (combine)
- `retry-after` typically < 60 seconds
- Implement exponential backoff for retries
---
## Job APIs
### Create Job
**Endpoint:** `POST /scheduler/jobs`
**Request Body:**
| Parameter | Required | Type | Description |
|-----------|----------|------|-------------|
| name | Yes | string | Job name (no special chars, not only numbers) |
| description | Yes | string | Job description |
| action | Yes | string | Fully qualified URL endpoint |
| active | Yes | boolean | Activation status |
| httpMethod | Yes | string | GET, POST, PUT, or DELETE |
| schedules | Yes | array | One or more schedules |
| startTime | No | string/object | Job start time |
| endTime | No | string/object/null | Job end time |
| ansConfig | No | object | Alert Notification config |
| calmConfig | No | object | Cloud ALM config |
**Schedule Parameters:**
| Parameter | Required | Type | Description |
|-----------|----------|------|-------------|
| active | Yes | boolean | Schedule activation |
| description | No | string | Schedule description |
| data | No | object | Payload for action endpoint |
| startTime | No | string/object | Schedule start |
| endTime | No | string/object | Schedule end |
| cron | No | string | Cron expression |
| time | No | string | One-time execution |
| repeatInterval | No | string | Recurring interval |
| repeatAt | No | string | Daily execution time |
**Note:** Specify at most ONE scheduling mode (cron, time, repeatInterval, repeatAt).
**Example Request:**
```json
POST /scheduler/jobs
{
"name": "salesReportJob",
"description": "Generate daily sales report",
"action": "[https://myapp.cfapps.eu10.hana.ondemand.com/api/reports/sales",](https://myapp.cfapps.eu10.hana.ondemand.com/api/reports/sales",)
"active": true,
"httpMethod": "POST",
"schedules": [{
"active": true,
"description": "Daily at 6 AM UTC",
"repeatAt": "6.00am",
"startTime": {
"date": "2025-01-01",
"format": "YYYY-MM-DD"
}
}],
"ansConfig": {
"onSuccess": false,
"onError": true
},
"calmConfig": {
"enabled": true
}
}
```
**Response (201 Created):**
```json
{
"name": "salesReportJob",
"description": "Generate daily sales report",
"action": "[https://myapp.cfapps.eu10.hana.ondemand.com/api/reports/sales",](https://myapp.cfapps.eu10.hana.ondemand.com/api/reports/sales",)
"active": true,
"httpMethod": "POST",
"_id": 42,
"schedules": [{
"scheduleId": "5f58c2fb-a428-4f4b-9e1d-312e3be8952c",
"active": true,
"type": "recurring"
}]
}
```
Location header: `/scheduler/jobs/42`
**Error Response (400):**
```json
{
"error": {
"code": "INVALID_REQUEST",
"message": "Invalid data provided",
"type": "VALIDATION_ERROR",
"detailedError": "Job name must not contain special characters"
}
}
```
### Retrieve All Jobs
**Endpoint:** `GET /scheduler/jobs`
**Query Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| name | string | Filter by job name |
| jobId | number | Filter by job ID |
| jobType | string | HTTP_ENDPOINT or CF_TASK |
| page_size | number | Results per page (default 10) |
| offset | number | Jobs to skip (default 1) |
| tenantId | string | Filter by tenant (XSUAA token required) |
**OData-Style Filtering:**
```
GET /scheduler/jobs?$filter=name eq 'myJob'
GET /scheduler/jobs?$filter=contains(name, 'report')
GET /scheduler/jobs?$filter=name eq 'job1' or name eq 'job2'
```
Operators: `eq`, `contains()`, `and`, `or`
**Response (200):**
```json
{
"total": 25,
"results": [
{
"_id": 1,
"name": "salesReportJob",
"description": "...",
"action": "...",
"active": true,
"httpMethod": "POST",
"jobType": "HTTP_ENDPOINT",
"createdAt": "2025-01-15T10:30:00Z",
"modifiedAt": "2025-01-20T14:00:00Z"
}
],
"prev_url": null,
"next_url": "/scheduler/jobs?offset=11&page_size=10"
}
```
### Retrieve Job Details
**Endpoints:**
- `GET /scheduler/jobs/{jobId}`
- `GET /scheduler/jobs?jobId={jobId}`
- `GET /scheduler/jobs?name={jobName}`
**Query Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| displaySchedules | boolean | Include schedule details |
**Example:**
```
GET /scheduler/jobs/42?displaySchedules=true
```
**Response (200):**
```json
{
"_id": 42,
"name": "salesReportJob",
"description": "Generate daily sales report",
"action": "[https://myapp.../api/reports/sales",](https://myapp.../api/reports/sales",)
"active": true,
"httpMethod": "POST",
"startTime": null,
"endTime": null,
"signatureVersion": 0,
"ansConfig": { "onSuccess": false, "onError": true },
"calmConfig": { "enabled": true },
"schedules": [{
"scheduleId": "5f58c2fb-...",
"description": "Daily at 6 AM UTC",
"type": "recurring",
"repeatAt": "6.00am",
"active": true,
"startTime": { "date": "2025-01-01", "format": "YYYY-MM-DD" }
}]
}
```
### Configure Job (Update)
**Endpoint:** `PUT /scheduler/jobs/{jobId}`
**Request Body:**
All parameters optional except at least one must be provided:
```json
PUT /scheduler/jobs/42
{
"active": false,
"description": "Updated description",
"httpMethod": "GET"
}
```
**Response (200):**
```json
{
"success": true
}
```
### Configure Job by Name (Create or Update)
**Endpoint:** `PUT /scheduler/jobs/{name}`
**Purpose:** Update an existing job or create a new one using the job name as identifier.
**Path Parameter:**
- `name` (string, required): Job name to update or create
**Request Body:**
| Parameter | Required | Type | Default | Description |
|-----------|----------|------|---------|-------------|
| description | No | string | empty | Job description |
| active | No | boolean | false | Activation status |
| action | Yes (create) | string | - | Action endpoint URL |
| httpMethod | No | string | POST | GET, POST, PUT, DELETE |
| endTime | No | string/object/null | null | Job end time |
| ansConfig | No | object | - | Alert Notification config |
| calmConfig | No | object | - | Cloud ALM config |
**Important:** The job name in the request URI must match the job name in the request body.
**Example Request:**
```json
PUT /scheduler/jobs/dailyReport
{
"name": "dailyReport",
"description": "Generate daily sales report",
"action": "[https://myapp.../api/reports",](https://myapp.../api/reports",)
"active": true,
"httpMethod": "POST"
}
```
**Response Codes:**
| Code | Description |
|------|-------------|
| 200 | Job updated successfully |
| 201 | New job created |
| 400 | Invalid data (validation errors) |
---
### Delete Job
**Endpoint:** `DELETE /scheduler/jobs/{jobId}`
**Behavior:**
- Removes job and all associated data
- Terminates all schedules (active and inactive)
- Deletes all run logs
**Example:**
```
DELETE /scheduler/jobs/42
```
**Response (200):**
```json
{
"success": true
}
```
**Response (404):** Invalid job ID
---
## Schedule APIs
### Create Schedule
**Endpoint:** `POST /scheduler/jobs/{jobId}/schedules`
**Request Body:**
```json
{
"active": true,
"description": "Every 2 hours",
"repeatInterval": "2 hours",
"startTime": {
"date": "2025-01-01",
"format": "YYYY-MM-DD"
},
"data": {
"customParam": "value"
}
}
```
**Response (201):**
```json
{
"scheduleId": "cb5c9def-e2a0-4294-8a51-61e4db373f99",
"description": "Every 2 hours",
"type": "recurring",
"repeatInterval": "2 hours",
"active": true,
"startTime": "2025-01-01T00:00:00.000Z",
"jobId": 42
}
```
### Retrieve Schedules
**Endpoint:** `GET /scheduler/jobs/{jobId}/schedules`
**Query Parameters:**
| Parameter | Type | Default |
|-----------|------|---------|
| page_size | number | 10 |
| offset | number | 1 |
### Retrieve Schedule Details
**Endpoint:** `GET /scheduler/jobs/{jobId}/schedules/{scheduleId}`
**Path Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| jobId | integer | Job identifier |
| scheduleId | string | Schedule identifier |
**Query Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| displayLogs | boolean | Return schedule run logs (max 200) |
**Example:**
```
GET /scheduler/jobs/42/schedules/cb5c9def-...?displayLogs=true
```
**Response (200):**
```json
{
"scheduleId": "cb5c9def-e2a0-4294-8a51-61e4db373f99",
"description": "Every 2 hours",
"data": {},
"type": "recurring",
"cron": null,
"repeatInterval": "2 hours",
"active": true,
"startTime": "2025-01-01T00:00:00.000Z",
"endTime": null,
"nextRunAt": "2025-01-20T14:00:00.000Z",
"logs": [
{
"runId": "ea16b621-...",
"executionTimestamp": "2025-01-20T12:00:05Z",
"httpStatus": 200,
"runStatus": "COMPLETED",
"runState": "SUCCESS"
}
]
}
```
**Response (404):** Invalid Job ID
---
### Configure Schedule
**Endpoint:** `PUT /scheduler/jobs/{jobId}/schedules/{scheduleId}`
**Constraint:** Cannot change scheduling modes (e.g., cron to repeatInterval). Only update values within same mode.
**Request:**
```json
PUT /scheduler/jobs/42/schedules/cb5c9def-...
{
"active": false,
"repeatInterval": "4 hours"
}
```
### Delete Schedule
**Endpoint:** `DELETE /scheduler/jobs/{jobId}/schedules/{scheduleId}`
### Delete All Schedules
**Endpoint:** `DELETE /scheduler/jobs/{jobId}/schedules`
### Activate/Deactivate All Schedules
**Endpoint:** `POST /scheduler/jobs/{jobId}/schedules/activationStatus`
**Request:**
```json
{
"activationStatus": true // or false
}
```
**Response:**
```json
{
"success": true
}
```
---
## Run Log APIs
### Retrieve Run Logs
**Endpoint:** `GET /scheduler/jobs/{jobId}/schedules/{scheduleId}/runs`
**Query Parameters:**
| Parameter | Type | Default | Max |
|-----------|------|---------|-----|
| page_size | number | 10 | 200 |
| offset | number | 1 | - |
**Response (200):**
```json
{
"total": 150,
"results": [{
"runId": "ea16b621-eaa8-4824-8629-ff6e6221bb56",
"runText": "Completed successfully",
"httpStatus": 200,
"executionTimestamp": "2025-01-20T06:00:05Z",
"scheduleTimestamp": "2025-01-20T06:00:00Z",
"completionTimestamp": "2025-01-20T06:00:10Z",
"runStatus": "COMPLETED",
"runState": "SUCCESS"
}],
"prev_url": null,
"next_url": "/scheduler/jobs/42/schedules/.../runs?offset=11"
}
```
**Timestamp Meanings:**
| Timestamp | Description |
|-----------|-------------|
| scheduleTimestamp | When schedule was picked up for calculation |
| executionTimestamp | When scheduler invoked action endpoint |
| completionTimestamp | When scheduler received response |
### Retrieve Run Log Details
**Endpoint:** `GET /scheduler/jobs/{jobId}/schedules/{scheduleId}/runs/{runId}`
**Path Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| jobId | integer | Job identifier |
| scheduleId | string | Schedule identifier |
| runId | string | Run identifier |
**Example:**
```
GET /scheduler/jobs/2/schedules/5f58c2fb-.../runs/5646889BB133728EE10000000A61A0D8
```
**Response (200):**
```json
{
"runId": "5646889BB133728EE10000000A61A0D8",
"runText": "Job completed successfully",
"httpStatus": 200,
"executionTimestamp": "2025-01-20T06:00:05Z",
"scheduleTimestamp": "2025-01-20T06:00:00Z",
"completionTimestamp": "2025-01-20T06:00:10Z",
"runStatus": "COMPLETED",
"runState": "SUCCESS"
}
```
**Response (404):** Invalid Job ID
---
### Update Run Log (Async Callback)
**Endpoint:** `PUT /scheduler/jobs/{jobId}/schedules/{scheduleId}/runs/{runId}`
**Purpose:** Application callback to report async job completion status.
**Request:**
```json
{
"success": true,
"message": "Processing completed: 1000 records processed"
}
```
**Response (200):**
```json
{
"success": true
}
```
**Implementation Notes:**
- IDs come from request headers during job invocation
- Single callback per run (not multiple updates)
- If not called, status becomes `UNKNOWN` after timeout
---
## Node.js Client Library
### Installation
```bash
npm install @sap/jobs-client
```
**Minimum Version:** 1.6.3 (for x509 certificate support)
### Initialization
```javascript
const JobSchedulerClient = require('@sap/jobs-client');
const scheduler = new JobSchedulerClient.Scheduler();
// Get credentials from VCAP_SERVICES
const vcapServices = JSON.parse(process.env.VCAP_SERVICES);
const jobSchedulerCredentials = vcapServices.jobscheduler[0].credentials;
```
### Job Management Methods
**createJob:**
```javascript
scheduler.createJob({
url: jobSchedulerCredentials.url
}, {
name: 'myJob',
description: 'My scheduled job',
action: '[https://myapp.../api/process',](https://myapp.../api/process',)
active: true,
httpMethod: 'POST',
schedules: [{
cron: '* * * * 9 0 0',
active: true,
description: 'Daily at 9 AM'
}]
}, (error, result) => {
if (error) {
console.error('Error:', error);
} else {
console.log('Job created:', result);
}
});
```
**fetchJob:**
```javascript
scheduler.fetchJob({
url: jobSchedulerCredentials.url,
jobId: 42 // or jobName: 'myJob'
}, (error, result) => { /* ... */ });
```
**updateJob:**
```javascript
scheduler.updateJob({
url: jobSchedulerCredentials.url,
jobId: 42
}, {
active: false
}, (error, result) => { /* ... */ });
```
**deleteJob:**
```javascript
scheduler.deleteJob({
url: jobSchedulerCredentials.url,
jobId: 42
}, (error, result) => { /* ... */ });
```
**fetchAllJobs:**
```javascript
scheduler.fetchAllJobs({
url: jobSchedulerCredentials.url
}, (error, result) => { /* ... */ });
```
**getJobCount:**
```javascript
scheduler.getJobCount({
url: jobSchedulerCredentials.url
}, (error, result) => {
console.log('Active jobs:', result.activeJobs);
console.log('Inactive jobs:', result.inactiveJobs);
});
```
### Schedule Management Methods
```javascript
// Create schedule
scheduler.createJobSchedule({
url: jobSchedulerCredentials.url,
jobId: 42
}, {
repeatInterval: '2 hours',
active: true
}, callback);
// Update schedule
scheduler.updateJobSchedule({
url: jobSchedulerCredentials.url,
jobId: 42,
scheduleId: 'cb5c9def-...'
}, {
active: false
}, callback);
// Delete schedule
scheduler.deleteJobSchedule({
url: jobSchedulerCredentials.url,
jobId: 42,
scheduleId: 'cb5c9def-...'
}, callback);
// Fetch schedules
scheduler.fetchJobSchedules({
url: jobSchedulerCredentials.url,
jobId: 42
}, callback);
// Bulk operations
scheduler.activateAllSchedules({ url, jobId }, callback);
scheduler.deactivateAllSchedules({ url, jobId }, callback);
scheduler.deleteAllJobSchedules({ url, jobId }, callback);
```
### Run Log Methods
```javascript
// Update run log (async callback)
scheduler.updateJobRunLog({
url: jobSchedulerCredentials.url,
jobId: jobId,
scheduleId: scheduleId,
runId: runId
}, {
success: true,
message: 'Processing completed'
}, callback);
// Get run logs
scheduler.getRunLogs({
url: jobSchedulerCredentials.url,
jobId: 42,
scheduleId: 'cb5c9def-...'
}, callback);
// Get action logs
scheduler.getJobActionLogs({ url, jobId }, callback);
scheduler.getScheduleActionLogs({ url, jobId, scheduleId }, callback);
```
### Complete Example
```javascript
const express = require('express');
const JobSchedulerClient = require('@sap/jobs-client');
const app = express();
const scheduler = new JobSchedulerClient.Scheduler();
const credentials = JSON.parse(process.env.VCAP_SERVICES).jobscheduler[0].credentials;
// Async job endpoint
app.post('/api/process', (req, res) => {
const jobId = req.headers['x-sap-job-id'];
const scheduleId = req.headers['x-sap-job-schedule-id'];
const runId = req.headers['x-sap-job-run-id'];
// Acknowledge immediately
res.status(202).json({ message: 'Accepted' });
// Process asynchronously
processAsync()
.then(() => {
scheduler.updateJobRunLog({
url: credentials.url,
jobId: parseInt(jobId),
scheduleId,
runId
}, {
success: true,
message: 'Completed successfully'
}, (err) => {
if (err) console.error('Failed to update run log:', err);
});
})
.catch((error) => {
scheduler.updateJobRunLog({
url: credentials.url,
jobId: parseInt(jobId),
scheduleId,
runId
}, {
success: false,
message: error.message
}, (err) => {
if (err) console.error('Failed to update run log:', err);
});
});
});
async function processAsync() {
// Long-running operation
}
app.listen(process.env.PORT || 3000);
```
---
## Java Client Library (XS Advanced)
### Overview
A Java Client Library (`java-js-client`) is available for SAP HANA Platform XS Advanced environments.
**Use Case:** For Java-based applications running on SAP HANA XS Advanced.
**Note:** This library is specific to XS Advanced and not for general Cloud Foundry Java applications. For Cloud Foundry Java apps, use the REST API directly with standard HTTP clients.
### Availability
Available through SAP's internal package registry for XS Advanced development.
---
## External References
### SAP Documentation
- **REST API Reference**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/sap-job-scheduling-service-rest-apis](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/sap-job-scheduling-service-rest-apis)
- **Node.js Client**: [https://www.npmjs.com/package/@sap/jobs-client](https://www.npmjs.com/package/@sap/jobs-client)
- **Java Client (XS Advanced)**: Available via SAP HANA XS Advanced documentation
- **Authentication**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/authentication](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/authentication)
### Source Files
- `sap-job-scheduling-service-rest-apis-c513d2d.md`
- `authentication-5dca60b.md`
- `rate-limits-a9cb164.md`
- `create-job-2c1ecb6.md`
- `retrieve-all-jobs-b4d3719.md`
- `node-js-client-library-9b86127.md`
- All schedule and run log documentation files

437
references/security.md Normal file
View File

@@ -0,0 +1,437 @@
# SAP BTP Job Scheduling Service - Security Guide
**Source**: [https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs/50---Security](https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs/50---Security)
**Last Updated**: 2025-11-22
---
## Table of Contents
1. [Security Overview](#security-overview)
2. [OAuth 2.0 Authentication](#oauth-20-authentication)
3. [XSUAA Configuration](#xsuaa-configuration)
4. [Scope Management](#scope-management)
5. [Credential Rotation](#credential-rotation)
6. [Data Protection](#data-protection)
7. [Best Practices](#best-practices)
---
## Security Overview
### Authentication Methods
| Service Plan | Authentication | Protocol |
|--------------|----------------|----------|
| lite | HTTP Basic Auth | HTTPS |
| standard | OAuth 2.0 | HTTPS |
### Security Architecture
```
┌─────────────────┐ OAuth Token ┌──────────────────┐
│ Job Scheduling │ ───────────────── │ Your App │
│ Service │ │ (Action Endpoint)│
└────────┬────────┘ └────────┬─────────┘
│ │
│ Token Request │ Token Validation
│ │
└──────────────┬──────────────────────┘
┌────────┴────────┐
│ XSUAA │
│ (Token Issuer) │
└─────────────────┘
```
### Key Security Features
- OAuth 2.0 protected communication for API access
- OAuth 2.0 protected job action endpoint invocation
- Token-based authentication with configurable scopes
- Support for X.509 certificate-based authentication
- Credential rotation via binding/unbinding
---
## OAuth 2.0 Authentication
### Token Flow for Job Execution
1. **Job Scheduling requests token** from XSUAA using service credentials
2. **XSUAA validates credentials** and returns access token with granted scopes
3. **Job Scheduling calls action endpoint** with Bearer token in Authorization header
4. **Application validates token** using bound XSUAA instance
5. **Application processes request** if token is valid
### Token Acquisition
**Client Credentials Flow (clientsecret):**
```bash
curl -X POST "[https://<uaa-url>/oauth/token"](https://<uaa-url>/oauth/token") \
-H "Authorization: Basic $(echo -n '<clientid>:<clientsecret>' | base64)" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials"
```
**Certificate-Based Authentication:**
```bash
curl -X POST "[https://<certurl>/oauth/token"](https://<certurl>/oauth/token") \
--cert /path/to/certificate.pem \
--key /path/to/key.pem \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=<clientid>"
```
### Token Response
```json
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 43199,
"scope": "uaa.resource my-app.JOBSCHEDULER",
"jti": "abc123..."
}
```
### Token Caching
- Tokens cached for up to **12 hours**
- Scope changes may take time to propagate
- If scope names change, cached tokens may cause errors
---
## XSUAA Configuration
### xs-security.json Structure
```json
{
"xsappname": "<application-name>",
"tenant-mode": "dedicated",
"scopes": [
{
"name": "$XSAPPNAME.JOBSCHEDULER",
"description": "Job Scheduler Scope",
"grant-as-authority-to-apps": [
"$XSSERVICENAME(<jobscheduler-instance-name>)"
]
}
],
"authorities": [
"$XSAPPNAME.JOBSCHEDULER"
]
}
```
### Configuration Elements
| Element | Purpose |
|---------|---------|
| `xsappname` | Unique application identifier |
| `tenant-mode` | Multitenancy mode (dedicated/shared) |
| `scopes` | OAuth scopes definition |
| `grant-as-authority-to-apps` | Grant scope to other services |
| `authorities` | Scopes the app can request |
### Variable Substitution
| Variable | Resolves To |
|----------|-------------|
| `$XSAPPNAME` | Value of `xsappname` field |
| `$XSSERVICENAME(name)` | Service instance identifier |
### Create/Update XSUAA Instance
**Create:**
```bash
cf create-service xsuaa application my-xsuaa -c xs-security.json
```
**Update:**
```bash
cf update-service my-xsuaa -c xs-security.json
```
**Bind:**
```bash
cf bind-service my-app my-xsuaa
cf restage my-app
```
---
## Scope Management
### Granting Scopes to Job Scheduling
The `grant-as-authority-to-apps` property enables Job Scheduling to obtain your application's scopes:
```json
{
"scopes": [{
"name": "$XSAPPNAME.JOBSCHEDULER",
"description": "Job Scheduler Scope",
"grant-as-authority-to-apps": [
"$XSSERVICENAME(my-jobscheduler)"
]
}]
}
```
### Multiple Scopes
Grant multiple scopes if your application requires different permissions:
```json
{
"scopes": [
{
"name": "$XSAPPNAME.JobRead",
"description": "Read job data",
"grant-as-authority-to-apps": ["$XSSERVICENAME(my-jobscheduler)"]
},
{
"name": "$XSAPPNAME.JobWrite",
"description": "Write job data",
"grant-as-authority-to-apps": ["$XSSERVICENAME(my-jobscheduler)"]
}
]
}
```
### Verifying Scope Grants
**Get Token Manually:**
```bash
# Get token using Job Scheduling credentials
curl -X POST "<job-scheduler-uaa-url>/oauth/token" \
-H "Authorization: Basic $(echo -n '<clientid>:<clientsecret>' | base64)" \
-d "grant_type=client_credentials"
```
**Decode Token (jwt.io or similar):**
Check the `scope` claim includes your granted scopes.
### Troubleshooting Scope Issues
| Issue | Cause | Solution |
|-------|-------|----------|
| Scope not in token | Not granted | Update xs-security.json |
| 401 on action endpoint | Token invalid | Verify XSUAA binding |
| Scope grant delayed | Token caching | Wait up to 12 hours |
---
## Credential Rotation
### Process Overview
Credentials are binding-level, meaning new credentials are created each time you bind the service.
### Rotation Steps
**1. Unbind Service:**
```bash
cf unbind-service my-app my-jobscheduler
```
**2. Rebind Service:**
```bash
cf bind-service my-app my-jobscheduler
```
**3. Restage Application:**
```bash
cf restage my-app
```
### Key Points
| Aspect | Behavior |
|--------|----------|
| Old credentials | Invalidated immediately on unbind |
| New credentials | Generated automatically on rebind |
| Token requests | Will fail with old credentials after unbind |
| Downtime | Brief during restage |
### X.509 Certificate Rotation
For certificate-based bindings:
```bash
# Unbind
cf unbind-service my-app my-jobscheduler
# Rebind with new certificate parameters
cf bind-service my-app my-jobscheduler -c parameters.json
# Restage
cf restage my-app
```
Certificate parameters.json:
```json
{
"credential-type": "x509",
"x509": {
"key-length": 2048,
"validity": 30,
"validity-type": "DAYS"
}
}
```
### Zero-Downtime Rotation (Advanced)
For production systems requiring zero downtime:
1. Create second service binding (if supported)
2. Update application to use new binding
3. Remove old binding
---
## Data Protection
### Personal Data Handling
The Job Scheduling service does **not** provide technical capabilities to support collection, processing, and storage of personal data.
### Fields NOT Intended for Personal Data
| Field | Risk |
|-------|------|
| Job names | Visible in logs and dashboard |
| Schedule descriptions | Stored in service database |
| Response message text | Stored in run logs |
| Custom data payloads | Passed to action endpoints |
### Compliance Considerations
- Data protection requires case-by-case evaluation
- Organizations must assess specific legal requirements
- SAP does not provide legal advice
- System landscape configuration affects compliance
### Run Log Retention
- Run logs automatically deleted after **15 days**
- Download logs before deletion if needed for compliance
- Consider data classification before including sensitive info
---
## Best Practices
### HTTPS Requirements
- **Always use HTTPS** for action endpoints in production
- HTTP allowed only for development/testing
- Dashboard enforces HTTPS requirement for job creation
### Scope Naming
- Use descriptive, consistent scope names
- Include purpose in scope descriptions
- Follow naming conventions: `$XSAPPNAME.<PurposeDescription>`
### Credential Management
| Practice | Recommendation |
|----------|----------------|
| Storage | Never hardcode credentials |
| Rotation | Rotate quarterly minimum |
| X.509 | Prefer certificates over secrets |
| Validity | Set appropriate certificate validity |
### Token Validation
Implement proper token validation in action endpoints:
```javascript
const xsenv = require('@sap/xsenv');
const passport = require('passport');
const { JWTStrategy } = require('@sap/xssec');
// Configure passport with XSUAA
const services = xsenv.getServices({ uaa: { tag: 'xsuaa' } });
passport.use(new JWTStrategy(services.uaa));
// Protect endpoint
app.post('/api/process',
passport.authenticate('JWT', { session: false }),
(req, res) => {
// Validate specific scope
if (!req.authInfo.checkScope('$XSAPPNAME.JOBSCHEDULER')) {
return res.status(403).send('Forbidden');
}
// Process request
}
);
```
**Required packages:**
```bash
npm install @sap/xsenv @sap/xssec passport
```
### Cloud Foundry Tasks
- CF tasks use Cloud Foundry UAA (CFUAA), not XSUAA
- XSUAA binding not required for CF task creation
- Space Developer role required for task management
---
## Security Checklist
### Initial Setup
- [ ] XSUAA instance created with xs-security.json
- [ ] Scopes defined with appropriate descriptions
- [ ] `grant-as-authority-to-apps` configured for Job Scheduling
- [ ] XSUAA bound to application before Job Scheduling
- [ ] Application restaged after bindings
### Action Endpoint
- [ ] HTTPS enabled (required for production)
- [ ] Token validation implemented
- [ ] Scope verification in endpoint handler
- [ ] Error handling for auth failures
### Ongoing Operations
- [ ] Credential rotation scheduled (quarterly)
- [ ] Token caching behavior understood
- [ ] Run log retention policy defined
- [ ] Personal data handling documented
---
## External References
### SAP Documentation
- **Security Overview**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/security](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/security)
- **Secure Access**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/secure-access](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/secure-access)
- **XSUAA Documentation**: [https://help.sap.com/docs/btp/sap-business-technology-platform/security](https://help.sap.com/docs/btp/sap-business-technology-platform/security)
### Source Files
- `security-9fb8213.md`
- `secure-access-745ca50.md`
- `define-and-grant-scopes-to-sap-job-scheduling-service-08933d3.md`
- `credential-rotation-ed3bf28.md`

397
references/setup-guide.md Normal file
View File

@@ -0,0 +1,397 @@
# SAP BTP Job Scheduling Service - Setup Guide
**Source**: [https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs](https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs)
**Last Updated**: 2025-11-22
---
## Table of Contents
1. [Prerequisites](#prerequisites)
2. [Service Plans](#service-plans)
3. [Create Service Instance - BTP Cockpit](#create-service-instance---btp-cockpit)
4. [Create Service Instance - CF CLI](#create-service-instance---cf-cli)
5. [Create Service Instance - Kyma Dashboard](#create-service-instance---kyma-dashboard)
6. [XSUAA Configuration](#xsuaa-configuration)
7. [Complete Setup Workflow](#complete-setup-workflow)
---
## Prerequisites
### Account Requirements
| Requirement | Description |
|-------------|-------------|
| Global Account | SAP BTP global account |
| Subaccount | At least one subaccount with CF or Kyma enabled |
| Administrator Role | Global account administrator |
| Quota | Purchased quota for Job Scheduling and XSUAA services |
### Service Entitlements
| Service | Plan | Purpose |
|---------|------|---------|
| SAP Job Scheduling Service | standard | Job scheduling functionality |
| SAP Authorization and Trust Management (XSUAA) | application | OAuth 2.0 authentication |
### Cloud Foundry Requirements
- Created a Cloud Foundry space
- Assigned as Space Developer in your space
- Application deployed with exposed action endpoint
- Application and service in the same CF space (co-location required)
### Kyma Requirements
- Kyma environment enabled in subaccount
- Namespace created
- One of these roles:
- `SAP_Job_Scheduling_Service_Admin`
- `SAP_Job_Scheduling_Service_Viewer`
---
## Service Plans
### Standard Plan
The only available plan for SAP Job Scheduling Service.
| Feature | Value |
|---------|-------|
| Authentication | OAuth 2.0 |
| Service Name | `jobscheduler` |
| Plan Name | `standard` |
| Custom Parameters | None required (see below) |
**Note (November 2024 Update):** The `enable-xsuaa-support` property now **defaults to enabled**. No additional parameters are required during service instance creation. Previously, this had to be explicitly set.
---
## Create Service Instance - BTP Cockpit
### Prerequisites
- Logged on to SAP BTP cockpit
- Quota assigned to subaccount
### Step-by-Step Instructions
**Step 1: Access Service Marketplace**
1. Navigate to your subaccount
2. Go to **Services****Service Marketplace**
3. Locate **Job Scheduling Service**
**Step 2: Create Instance**
1. Click on Job Scheduling Service tile
2. Open **Actions** menu
3. Select **Create**
4. New Instance wizard launches
**Step 3: Configure Instance**
| Field | Value |
|-------|-------|
| Service Plan | standard (only option) |
| Instance Name | Your custom name (e.g., `my-jobscheduler`) |
| Parameters | None available |
**Step 4: Complete Creation**
1. Click **Next** through Parameters step (no customization available)
2. Review details
3. Click **Create**
**Step 5: Bind to Application**
1. Go to **Service Instances**
2. Select your new instance
3. Click **Bind Application**
4. Select your deployed Cloud Foundry application
---
## Create Service Instance - CF CLI
### Prerequisites
- CF CLI installed
- Logged into Cloud Foundry (`cf login`)
- Application deployed
### Commands
**1. Verify Service Availability:**
```bash
cf marketplace
```
Look for `jobscheduler` in the output.
**2. Create Service Instance:**
```bash
cf create-service jobscheduler standard my-jobscheduler
```
**3. Bind Service - Basic:**
```bash
cf bind-service my-app my-jobscheduler
```
**4. Bind Service - With X.509 Certificate:**
Create `parameters.json`:
```json
{
"credential-type": "x509",
"x509": {
"key-length": 2048,
"validity": 7,
"validity-type": "DAYS"
}
}
```
Bind with parameters:
```bash
cf bind-service my-app my-jobscheduler -c parameters.json
```
**5. Restage Application:**
```bash
cf restage my-app
```
**6. Verify Binding:**
```bash
cf env my-app
```
Check `VCAP_SERVICES` for `jobscheduler` credentials.
### VCAP_SERVICES Structure
**Standard Binding (clientsecret):**
```json
{
"jobscheduler": [{
"credentials": {
"url": "[https://jobscheduler-rest.cfapps.eu10.hana.ondemand.com",](https://jobscheduler-rest.cfapps.eu10.hana.ondemand.com",)
"uaa": {
"url": "[https://xxx.authentication.eu10.hana.ondemand.com",](https://xxx.authentication.eu10.hana.ondemand.com",)
"clientid": "sb-xxx",
"clientsecret": "xxx"
}
}
}]
}
```
**X.509 Binding:**
```json
{
"jobscheduler": [{
"credentials": {
"url": "[https://jobscheduler-rest.cfapps.eu10.hana.ondemand.com",](https://jobscheduler-rest.cfapps.eu10.hana.ondemand.com",)
"uaa": {
"certurl": "[https://xxx.authentication.cert.eu10.hana.ondemand.com",](https://xxx.authentication.cert.eu10.hana.ondemand.com",)
"clientid": "sb-xxx",
"certificate": "-----BEGIN CERTIFICATE-----\n...",
"key": "-----BEGIN RSA PRIVATE KEY-----\n..."
}
}
}]
}
```
---
## Create Service Instance - Kyma Dashboard
### Prerequisites
- Logged on to SAP BTP cockpit
- Kyma environment enabled
### Step-by-Step Instructions
**Step 1: Access Kyma Dashboard**
1. Navigate to your subaccount
2. Click **Link to Dashboard** in Kyma Environment section
**Step 2: Select Namespace**
1. Choose your target namespace
**Step 3: Create Service Instance**
1. Go to **Service Instances** section
2. Click **Create**
3. Fill in details:
| Field | Value |
|-------|-------|
| Service Name | `jobscheduler` |
| Plan | `standard` |
| Instance Name | Your custom name |
**Step 4: Create Service Binding**
1. Navigate to **Service Bindings**
2. Click **Create**
3. Select your service instance
4. Provide binding name
**Step 5: Mount Service in Application**
Connect the service binding to your application deployment using SAP BTP Operator module.
### Kyma-Specific Notes
- Use SAP BTP Operator for service management
- Service bindings mounted as Kubernetes secrets
- Refer to Kyma documentation for detailed deployment patterns
---
## XSUAA Configuration
### Purpose
XSUAA provides OAuth 2.0 authentication for job action endpoints. Job Scheduling Service needs scope grants to call protected endpoints.
### xs-security.json Template
```json
{
"xsappname": "my-app",
"tenant-mode": "dedicated",
"scopes": [
{
"name": "$XSAPPNAME.JOBSCHEDULER",
"description": "Job Scheduler Scope",
"grant-as-authority-to-apps": [
"$XSSERVICENAME(my-jobscheduler)"
]
}
],
"authorities": [
"$XSAPPNAME.JOBSCHEDULER"
]
}
```
### Key Configuration Elements
| Element | Description |
|---------|-------------|
| `$XSAPPNAME` | Automatically replaced with app name |
| `$XSSERVICENAME(instance)` | References Job Scheduling instance |
| `grant-as-authority-to-apps` | Grants scope to Job Scheduling service |
### Apply Configuration
**Create XSUAA Instance:**
```bash
cf create-service xsuaa application my-xsuaa -c xs-security.json
```
**Update Existing Instance:**
```bash
cf update-service my-xsuaa -c xs-security.json
```
**Bind XSUAA to Application:**
```bash
cf bind-service my-app my-xsuaa
cf restage my-app
```
### Scope Grant Workflow
1. Application defines scope in `xs-security.json`
2. Scope granted to Job Scheduling service via `grant-as-authority-to-apps`
3. Job Scheduling obtains token from UAA with granted scope
4. Job Scheduling includes token when calling action endpoint
5. Application validates token using bound XSUAA instance
---
## Complete Setup Workflow
### Recommended Order
```
1. Deploy Application
└─ Expose action endpoint (HTTPS)
2. Create XSUAA Instance
└─ Configure xs-security.json with scope grants
└─ cf create-service xsuaa application my-xsuaa -c xs-security.json
3. Bind XSUAA to Application
└─ cf bind-service my-app my-xsuaa
4. Create Job Scheduling Instance
└─ cf create-service jobscheduler standard my-jobscheduler
5. Bind Job Scheduling to Application
└─ cf bind-service my-app my-jobscheduler
6. Restage Application
└─ cf restage my-app
7. Create Jobs via REST API or Dashboard
```
### Verification Checklist
- [ ] Application deployed and accessible
- [ ] Action endpoint exposed and working
- [ ] XSUAA instance created with correct scopes
- [ ] XSUAA bound to application
- [ ] Job Scheduling instance created
- [ ] Job Scheduling bound to application
- [ ] Application restaged
- [ ] VCAP_SERVICES contains both services
- [ ] Can obtain OAuth token successfully
- [ ] Can access Job Scheduling dashboard
### Common Setup Errors
| Error | Cause | Solution |
|-------|-------|----------|
| Service not found | Missing entitlement | Add quota to subaccount |
| 401 Unauthorized | Missing scope grant | Update xs-security.json |
| 403 Forbidden | Wrong space | Ensure co-location |
| Instance not visible | Not bound | Bind service to app |
---
## External References
### SAP Documentation
- **Initial Setup**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/initial-setup](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/initial-setup)
- **Getting Started**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/getting-started](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/getting-started)
- **XSUAA Documentation**: [https://help.sap.com/docs/btp/sap-business-technology-platform/security](https://help.sap.com/docs/btp/sap-business-technology-platform/security)
### Source Files
- `initial-setup-0adb655.md`
- `create-a-service-instance-in-sap-btp-cockpit-e267ab6.md`
- `create-a-service-instance-using-cf-cli-cb56f9e.md`
- `create-a-service-instance-in-the-kyma-dashboard-224a49a.md`
- `getting-started-02e4e8b.md`

View File

@@ -0,0 +1,379 @@
# SAP BTP Job Scheduling Service - Troubleshooting Guide
**Source**: [https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs](https://github.com/SAP-docs/sap-btp-job-scheduling-service/tree/main/docs)
**Last Updated**: 2025-11-22
---
## Table of Contents
1. [Support Information](#support-information)
2. [Common Error Scenarios](#common-error-scenarios)
3. [Schedule Issues](#schedule-issues)
4. [Authentication Issues](#authentication-issues)
5. [Cloud Foundry Task Issues](#cloud-foundry-task-issues)
6. [Dashboard Access Issues](#dashboard-access-issues)
7. [Frequently Asked Questions](#frequently-asked-questions)
---
## Support Information
### Support Component
**Component:** `BC-CP-CF-JBS`
Use this component when creating SAP support tickets.
### Self-Service Resources
1. **SAP Trust Center** - Check platform status
2. **Guided Answers Tool** - Documented troubleshooting scenarios
3. **Platform Updates and Notifications** - Cloud Foundry environment updates
### Escalation Path
1. Check FAQ and troubleshooting scenarios
2. Verify platform status via SAP Trust Center
3. Use Guided Answers for common issues
4. Submit incident via SAP Support with component BC-CP-CF-JBS
---
## Common Error Scenarios
### Service Unavailability
**Symptoms:**
- Service missing from marketplace
- Service not visible in cockpit
**Diagnostic Steps:**
1. Verify service availability in your region (SAP BTP service portfolio)
2. Confirm quota assigned to subaccount
3. Check Space Developer role assignment
**Solutions:**
| Cause | Solution |
|-------|----------|
| No quota | Review [Managing Entitlements and Quotas](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/c8248745dde24afb91479361de336111.html) |
| Region unavailable | Create subaccount in supported region |
| Missing role | Request Space Developer role |
### REST API Authentication Errors
**Error:** HTTP Status Code 401
**Diagnostic Steps:**
1. Validate credentials being passed
2. Check token expiration
3. Verify correct endpoint URL
**Solutions:**
| Cause | Solution |
|-------|----------|
| Invalid credentials | Re-check VCAP_SERVICES values |
| Expired token | Request new token |
| Wrong endpoint | Use URL from service binding |
### OAuth Scope Issues
**Symptoms:**
- Granted scopes not in Job Scheduling tokens
- 403 Forbidden when calling action endpoint
**Diagnostic Steps:**
1. Manually retrieve token using Job Scheduling credentials:
```bash
curl -X POST "<uaa-url>/oauth/token" \
-H "Authorization: Basic <credentials>" \
-d "grant_type=client_credentials"
```
2. Decode token and verify scope claim
3. Note: Tokens cached up to 12 hours
**Solutions:**
| Cause | Solution |
|-------|----------|
| Missing grant | Update `grant-as-authority-to-apps` in xs-security.json |
| Stale cache | Wait up to 12 hours for token refresh |
| Wrong binding | Verify Job Scheduling instance name matches |
---
## Schedule Issues
### Schedule Fails to Execute
**Possible Causes:**
| Cause | Description |
|-------|-------------|
| Invalid format | Date-time or cron format incorrect |
| Past endTime | Schedule endTime is in the past |
| Wrong timezone | Service uses UTC only |
| Auto-deactivated | See auto-deactivation triggers below |
### Auto-Deactivation Triggers
Schedules automatically deactivate when:
1. **One-time schedule executed** - Successful or failed
2. **No valid future dates** - All possible execution times passed
3. **endTime reached** - Job or schedule end time in past
4. **Endpoint unreachable** - Action endpoint unreachable for 10+ consecutive days
### ACK_NOT_RECVD Status
**Meaning:** Application hasn't updated the run log after processing.
**Solution:**
- Implement async callback properly
- Call Update Job Run Log API after completion:
```
PUT /scheduler/jobs/{jobId}/schedules/{scheduleId}/runs/{runId}
{
"success": true,
"message": "Completed"
}
```
### Immediate Execution
**To execute a job immediately:**
Create one-time schedule with:
```json
{
"time": "now"
}
```
### Cron Format Errors
**Common Mistake:** Using Linux cron format
**Correct:** SAP cron format (7 fields):
```
[Year] [Month] [Day] [DayOfWeek] [Hour] [Minute] [Second]
```
**Example with field mapping:**
```
* * * * 9 0 0
Year Month Day DayOfWeek Hour Minute Second
// Daily at 9:00:00 AM UTC (SAP format)
```
NOT:
```
0 9 * * * // Linux format (5 fields) - will NOT work
```
**Note:** `*` is a wildcard meaning "any value" for that field.
### Timezone Issues
**Note:** Service operates in **UTC only**. No other timezones supported.
Convert local times to UTC before scheduling.
---
## Authentication Issues
### 401 Unauthorized
**Check List:**
- [ ] Correct OAuth token in Authorization header
- [ ] Token not expired
- [ ] Using Bearer token format
- [ ] Correct endpoint URL
### 403 Forbidden
**Check List:**
- [ ] Scope granted via `grant-as-authority-to-apps`
- [ ] xs-security.json updated and service restarted
- [ ] Application validates token correctly
- [ ] Same space for app and service (co-location)
### Dashboard Authorization Error (500)
**Symptom:** 500 error when accessing dashboard
**Solution:**
Grant permissions at UAA login route:
```
[https://uaa.cf.<region>.hana.ondemand.com/profile](https://uaa.cf.<region>.hana.ondemand.com/profile)
```
Example: `[https://uaa.cf.eu10.hana.ondemand.com/profile`](https://uaa.cf.eu10.hana.ondemand.com/profile`)
---
## Cloud Foundry Task Issues
### Unsuccessful Task Creation
**Diagnostic Steps:**
1. Check organization memory quota:
```bash
cf org <org-name> --guid
cf curl "/v2/organizations/<org-guid>/memory_usage"
```
2. Verify total available memory exceeds task requirements
3. Review application logs:
```bash
cf logs <application_name> --recent
```
**Solutions:**
| Cause | Solution |
|-------|----------|
| Insufficient quota | Request additional memory quota |
| Memory too high | Configure task memory via dashboard |
### Configure Task Memory
In dashboard, use JSON options:
```json
{
"memory_in_mb": 512
}
```
Default: 1024 MB (1 GB)
### CF Task Limitations
- Cannot create CF tasks via REST API
- Requires Space Developer role
- Must use dashboard for task creation
- Tasks always run asynchronously
---
## Dashboard Access Issues
### Prerequisites
- Space Developer role (full access)
- OR one of: SpaceAuditor, SpaceManager, OrgManager, SpaceSupporter (read-only)
### Access Methods
**Via BTP Cockpit:**
1. Navigate to subaccount
2. Go to **Service Instances**
3. Select Job Scheduling instance
4. Click **View Dashboard** or access via Service Bindings
**Via CF CLI:**
```bash
cf service <service-instance-name>
```
Look for dashboard URL in output.
### Kyma Dashboard Access
Requires one of:
- `SAP_Job_Scheduling_Service_Admin`
- `SAP_Job_Scheduling_Service_Viewer`
---
## Frequently Asked Questions
### General
**Q: What is the support component?**
A: BC-CP-CF-JBS
**Q: What are the prerequisites?**
A: Access to service in CF marketplace and xsuaa service for jobs with action endpoints.
**Q: What is the SLA?**
A: Scheduled jobs have approximately 20 minutes tolerance from scheduled execution time.
**Q: What do units on SAP Store represent?**
A: Each unit represents one creatable service instance.
### Multitenancy
**Q: How does multitenancy work?**
A: Multitenant applications can register jobs on behalf of subscribed tenants while maintaining tenant context awareness during execution.
**Q: What tokens are needed for multitenancy?**
A: Use client credentials flow with XSUAA to obtain access tokens.
**Q: What about tenantId filtering?**
A: The `tenantId` query parameter filters jobs when using client credentials tokens, but returns 400 for SaaS tenant tokens.
### Schedules
**Q: Why did my schedule auto-deactivate?**
A: One-time schedules deactivate after execution, recurring schedules deactivate when no valid future dates exist, endTime reached, or action endpoint unreachable for 10+ days.
**Q: What is ACK_NOT_RECVD?**
A: The application hasn't updated the run log after async processing. Call the Update Run Log API.
**Q: How do I execute immediately?**
A: Create one-time schedule with `"time": "now"`.
**Q: What cron format is used?**
A: SAP cron format (7 fields), NOT Linux cron format.
### API
**Q: Can CF tasks be created via REST API?**
A: No, only developers with Space Developer role can create them through the dashboard's Tasks section.
**Q: What is the request body size limit?**
A: 100 KB. Exceeding returns HTTP 413.
**Q: What timezone is used?**
A: UTC only. No other timezones supported.
### Data
**Q: How long are run logs retained?**
A: 15 days, then automatically deleted.
**Q: Can deleted jobs be restored?**
A: Yes, within time limits (14 days AWS/Azure, 7 days GCP). Same-day deletions cannot be restored.
---
## Error Code Reference
| Code | Meaning | Solution |
|------|---------|----------|
| 400 | Invalid request data | Check request body format |
| 401 | Unauthorized | Check credentials/token |
| 403 | Forbidden | Check scope grants |
| 404 | Not found | Verify job/schedule ID |
| 413 | Request too large | Reduce body size (<100KB) |
| 429 | Rate limit exceeded | Wait for retry-after period |
| 500 | Server error | Check dashboard auth |
| 503 | Service unavailable | Wait for throttling period |
---
## External References
### SAP Documentation
- **FAQ**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/frequently-asked-questions](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/frequently-asked-questions)
- **Troubleshooting**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/troubleshooting-scenarios](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/troubleshooting-scenarios)
- **Monitoring**: [https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/monitoring-and-troubleshooting](https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/monitoring-and-troubleshooting)
- **Guided Answers**: [https://ga.support.sap.com/](https://ga.support.sap.com/)
### Source Files
- `frequently-asked-questions-d72c276.md`
- `troubleshooting-scenarios-b05dc8c.md`
- `monitoring-and-troubleshooting-bd573bd.md`

View File

@@ -0,0 +1,76 @@
{
"_comment": "SAP BTP Job Scheduling Service - Job Creation Template",
"_documentation": "https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/create-job",
"_instructions": [
"1. Replace all [PLACEHOLDER] values with your actual values",
"2. Remove _comment, _documentation, _instructions fields before submitting",
"3. Choose ONE scheduling mode per schedule: cron, time, repeatInterval, or repeatAt",
"4. Use HTTPS for action endpoints in production",
"5. All times are interpreted as UTC"
],
"name": "[JOB_NAME]",
"description": "[JOB_DESCRIPTION]",
"action": "https://[YOUR_APP].[LANDSCAPE].hana.ondemand.com/api/[ENDPOINT]",
"active": true,
"httpMethod": "POST",
"startTime": {
"date": "[YYYY-MM-DD]",
"format": "YYYY-MM-DD"
},
"endTime": null,
"schedules": [
{
"_comment_schedule_type": "OPTION 1: Recurring with cron (7-field SAP format)",
"_cron_format": "SAP format: [Year] [Month] [Day] [DayOfWeek] [Hour] [Minute] [Second]",
"active": true,
"description": "[SCHEDULE_DESCRIPTION]",
"cron": "* * * * [HOUR] [MINUTE] [SECOND]",
"startTime": {
"date": "[YYYY-MM-DD]",
"format": "YYYY-MM-DD"
},
"data": {
"_comment": "Custom payload sent to action endpoint",
"param1": "value1"
}
}
],
"_alternative_schedule_types": {
"one_time": {
"time": "now",
"_or": "2025-12-31T23:59:59Z",
"_or_human": "tomorrow at 4pm"
},
"repeat_interval": {
"repeatInterval": "2 hours",
"_examples": ["5 minutes", "1 day", "2 weeks"]
},
"repeat_at": {
"repeatAt": "6.00am",
"_examples": ["4.40pm", "18:30", "6.20am"]
},
"cron_examples": {
"daily_9am": "* * * * 9 0 0",
"every_monday_10am": "* * * mon 10 0 0",
"last_sunday_monthly": "* * * -1.sun 9 0 0",
"every_30_min_10_to_12": "* * * * 10:12 0,30 0",
"first_of_month_6pm": "* * 1 * 18 0 0"
}
},
"ansConfig": {
"_comment": "SAP Alert Notification Service (Cloud Foundry only)",
"onSuccess": false,
"onError": true
},
"calmConfig": {
"_comment": "SAP Cloud ALM monitoring",
"enabled": true
}
}

View File

@@ -0,0 +1,66 @@
{
"_comment": "SAP XSUAA Configuration Template for Job Scheduling Service",
"_documentation": "https://help.sap.com/docs/job-scheduling/sap-job-scheduling-service/define-and-grant-scopes-to-sap-job-scheduling-service",
"_instructions": [
"1. Replace [APP_NAME] with your application name",
"2. Replace [JOBSCHEDULER_INSTANCE] with your Job Scheduling service instance name",
"3. Remove all _comment and _instructions fields before deployment",
"4. Create/update XSUAA: cf create-service xsuaa application my-xsuaa -c xs-security.json",
"5. Bind to app: cf bind-service my-app my-xsuaa && cf restage my-app"
],
"xsappname": "[APP_NAME]",
"tenant-mode": "dedicated",
"scopes": [
{
"name": "$XSAPPNAME.JOBSCHEDULER",
"description": "Job Scheduler Scope - Allows Job Scheduling service to invoke action endpoints",
"grant-as-authority-to-apps": [
"$XSSERVICENAME([JOBSCHEDULER_INSTANCE])"
]
}
],
"authorities": [
"$XSAPPNAME.JOBSCHEDULER"
],
"_additional_scopes_example": {
"_comment": "Add more scopes if your app needs different permission levels",
"scopes": [
{
"name": "$XSAPPNAME.JobRead",
"description": "Read job data",
"grant-as-authority-to-apps": ["$XSSERVICENAME([JOBSCHEDULER_INSTANCE])"]
},
{
"name": "$XSAPPNAME.JobWrite",
"description": "Write job data",
"grant-as-authority-to-apps": ["$XSSERVICENAME([JOBSCHEDULER_INSTANCE])"]
}
]
},
"_multitenant_example": {
"_comment": "For multitenant applications",
"tenant-mode": "shared",
"scopes": [
{
"name": "$XSAPPNAME.JOBSCHEDULER",
"description": "Job Scheduler Scope",
"grant-as-authority-to-apps": ["$XSSERVICENAME([JOBSCHEDULER_INSTANCE])"]
},
{
"name": "$XSAPPNAME.Callback",
"description": "Tenant callback scope",
"grant-as-authority-to-apps": ["sap-provisioning"]
}
]
},
"_variable_reference": {
"$XSAPPNAME": "Resolves to the value of xsappname field",
"$XSSERVICENAME(name)": "Resolves to the service instance identifier"
}
}