Initial commit
This commit is contained in:
12
.claude-plugin/plugin.json
Normal file
12
.claude-plugin/plugin.json
Normal 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
3
README.md
Normal 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
401
SKILL.md
Normal 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
85
plugin.lock.json
Normal 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
400
references/changelog.md
Normal 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
472
references/concepts.md
Normal 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
310
references/integrations.md
Normal 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
321
references/operations.md
Normal 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
937
references/rest-api.md
Normal 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
437
references/security.md
Normal 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
397
references/setup-guide.md
Normal 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`
|
||||
379
references/troubleshooting.md
Normal file
379
references/troubleshooting.md
Normal 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`
|
||||
76
templates/job-creation.json
Normal file
76
templates/job-creation.json
Normal 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
|
||||
}
|
||||
}
|
||||
66
templates/xs-security.json
Normal file
66
templates/xs-security.json
Normal 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"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user