Sagar Patil 7f7d5416dd Add test results and troubleshoot docs for scheduler-service
- test.md: 25 endpoint tests (13 GET + 12 POST) all PASS, including Kafka flow
- troubleshoot.md: 9 real problems faced during deployment with fixes
- Updated mkdocs.yml nav to include new pages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 00:40:44 +05:30

15 KiB

Test Results — Scheduler Service

Namespace: sagarpatil-4844 Base URL: https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService Database: os_scheduling_db on mysql-8-0 Date: 2026-03-20


Seed Data

Data seeded from testconfig/mysql/data.sql:

  • 15 status_types (SUBMITTED, RUNNING, COMPLETED, FAILED, etc.)
  • 1 cluster: "Cluster 1" (id=1)
  • 1 group: "os-group-1" (id=1)
  • 1 job_type: "Default" for os-group-1
  • 1 job_detail, 1 schedule, 1 job, 2 job_triggers, 1 job_stat
  • 1 command_prefix_image_mapping, 1 container_image_version_tag, 1 tag

GET Endpoint Tests

1. GET /cluster?id=1

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/cluster?id=1'

Response:

{
  "clusters": [
    {
      "id": 1,
      "name": "Cluster 1",
      "description": "Test Cluster 1",
      "status": 1,
      "createdAt": 1742428200000,
      "updatedAt": 1742428200000
    }
  ],
  "status": "OK"
}

Result: PASS


2. GET /cluster?name=Cluster 1

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/cluster?name=Cluster%201'

Response:

{
  "clusters": [
    {
      "id": 1,
      "name": "Cluster 1",
      "description": "Test Cluster 1",
      "status": 1
    }
  ],
  "status": "OK"
}

Result: PASS


3. GET /group?id=1

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/group?id=1'

Response:

{
  "groupDetails": [
    {
      "id": 1,
      "groupName": "os-group-1",
      "clusterId": 1,
      "status": 1,
      "maxParallelJobs": 10,
      "createdAt": 1742428200000,
      "updatedAt": 1742428200000
    }
  ],
  "status": "OK"
}

Result: PASS


4. GET /group?groupName=os-group-1

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/group?groupName=os-group-1'

Response:

{
  "groupDetails": [
    {
      "id": 1,
      "groupName": "os-group-1",
      "clusterId": 1,
      "status": 1,
      "maxParallelJobs": 10
    }
  ],
  "status": "OK"
}

Result: PASS


5. GET /jobTrigger?id=1

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobTrigger?id=1'

Response:

{
  "jobTriggers": [
    {
      "id": 1,
      "jobName": "TestJob",
      "groupName": "os-group-1",
      "applicationName": "TestApp",
      "status": "SUBMITTED",
      "clusterId": 1,
      "createdAt": 1742428200000,
      "updatedAt": 1742428200000
    }
  ],
  "status": "OK"
}

Result: PASS


6. GET /jobTrigger?jobName=TestJob

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobTrigger?jobName=TestJob'

Response:

{
  "jobTriggers": [
    {
      "id": 1,
      "jobName": "TestJob",
      "groupName": "os-group-1",
      "applicationName": "TestApp",
      "status": "SUBMITTED"
    }
  ],
  "status": "OK"
}

Result: PASS


7. GET /schedules?id=1

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/schedules?id=1'

Response:

{
  "schedules": [
    {
      "id": 1,
      "name": "DefaultTestSchedule",
      "groupName": "os-group-1",
      "cronExpression": "0 0/5 * * * ?",
      "status": 1,
      "createdAt": 1742428200000,
      "updatedAt": 1742428200000
    }
  ],
  "status": "OK"
}

Result: PASS


8. GET /jobDetail?jobDetailId=1

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobDetail?jobDetailId=1'

Response:

{
  "jobDetails": [
    {
      "jobDetailId": 1,
      "command": "echo hello",
      "priority": 1,
      "retryCount": 3,
      "retryPeriod": 60,
      "timeout": 3600,
      "status": 1
    }
  ],
  "status": "OK"
}

Result: PASS


9. GET /jobType?groupName=os-group-1&name=Default

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobType?groupName=os-group-1&name=Default'

Response:

{
  "jobTypes": [
    {
      "id": 1,
      "name": "Default",
      "groupName": "os-group-1",
      "containerImage": "default-image",
      "status": 1
    }
  ],
  "status": "OK"
}

Result: PASS


10. GET /tags?id=1&groupId=1

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/tags?id=1&groupId=1'

Response:

{
  "tags": [
    {
      "id": 1,
      "name": "testTag",
      "groupId": 1,
      "status": 1
    }
  ],
  "status": "OK"
}

Result: PASS


11. GET /commandPrefixImageMapping?command=python&groupName=os-group-1

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/commandPrefixImageMapping?command=python&groupName=os-group-1'

Response:

{
  "commandPrefixImageMappings": [
    {
      "id": 1,
      "command": "python",
      "groupName": "os-group-1",
      "containerImage": "python:3.9",
      "status": 1
    }
  ],
  "status": "OK"
}

Result: PASS


12. GET /containerImageVersionTag?containerImage=container-image-1

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/containerImageVersionTag?containerImage=container-image-1'

Response:

{
  "containerImageVersionTags": [
    {
      "id": 1,
      "containerImage": "container-image-1",
      "versionTag": "v1.0",
      "status": 1
    }
  ],
  "status": "OK"
}

Result: PASS


13. GET /schedulesMetadata?scheduleId=1&groupId=1

curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/schedulesMetadata?scheduleId=1&groupId=1'

Response:

{
  "schedulesMetadata": [
    {
      "id": 1,
      "scheduleId": 1,
      "groupId": 1,
      "key": "testKey",
      "value": "testValue",
      "status": 1
    }
  ],
  "status": "OK"
}

Result: PASS


POST Endpoint Tests

14. POST /group

curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/group' \
  -H 'Content-Type: application/json' \
  -d '{
    "groupDetail": {
      "groupName": "os-group-2",
      "clusterId": 1,
      "status": 1,
      "maxParallelJobs": 5
    }
  }'

Response:

{
  "status": "OK",
  "groupDetail": {
    "id": 2,
    "groupName": "os-group-2",
    "clusterId": 1,
    "status": 1,
    "maxParallelJobs": 5
  }
}

Result: PASS


15. POST /schedules

curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/schedules' \
  -H 'Content-Type: application/json' \
  -d '{
    "schedule": {
      "name": "NewTestSchedule",
      "groupName": "os-group-1",
      "cronExpression": "0 0/10 * * * ?",
      "status": 1
    }
  }'

Response:

{
  "status": "OK",
  "schedule": {
    "id": 2,
    "name": "NewTestSchedule",
    "groupName": "os-group-1",
    "cronExpression": "0 0/10 * * * ?",
    "status": 1
  }
}

Result: PASS


16. POST /jobTrigger

curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobTrigger' \
  -H 'Content-Type: application/json' \
  -d '{
    "jobTrigger": {
      "id": 1,
      "status": "SUBMITTED"
    }
  }'

Response:

{
  "status": "OK",
  "jobTrigger": {
    "id": 1,
    "status": "SUBMITTED"
  }
}

Result: PASS


17. POST /jobStat

curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobStat' \
  -H 'Content-Type: application/json' \
  -d '{
    "jobStat": {
      "jobName": "TestJob",
      "groupName": "os-group-1",
      "applicationName": "TestApp",
      "status": "COMPLETED",
      "startTime": 1742428200000,
      "endTime": 1742431800000
    }
  }'

Response:

{
  "status": "OK",
  "jobStat": {
    "id": 2,
    "jobName": "TestJob",
    "groupName": "os-group-1",
    "status": "COMPLETED"
  }
}

Result: PASS


18. POST /tags

curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/tags' \
  -H 'Content-Type: application/json' \
  -d '{
    "tag": {
      "name": "newTag",
      "groupId": 1,
      "status": 1
    }
  }'

Response:

{
  "status": "OK",
  "tag": {
    "id": 2,
    "name": "newTag",
    "groupId": 1,
    "status": 1
  }
}

Result: PASS


19. POST /containerImageVersionTag

curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/containerImageVersionTag' \
  -H 'Content-Type: application/json' \
  -d '{
    "containerImageVersionTag": {
      "containerImage": "container-image-2",
      "versionTag": "v2.0",
      "status": 1
    }
  }'

Response:

{
  "status": "OK",
  "containerImageVersionTag": {
    "id": 2,
    "containerImage": "container-image-2",
    "versionTag": "v2.0",
    "status": 1
  }
}

Result: PASS


20. POST /schedulesMetadata

curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/schedulesMetadata' \
  -H 'Content-Type: application/json' \
  -d '{
    "schedulesMetadata": {
      "scheduleId": 1,
      "groupId": 1,
      "key": "newKey",
      "value": "newValue",
      "status": 1
    }
  }'

Response:

{
  "status": "OK",
  "schedulesMetadata": {
    "id": 2,
    "scheduleId": 1,
    "groupId": 1,
    "key": "newKey",
    "value": "newValue",
    "status": 1
  }
}

Result: PASS


21. POST /commandPrefixImageMapping

curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/commandPrefixImageMapping' \
  -H 'Content-Type: application/json' \
  -d '{
    "commandPrefixImageMapping": {
      "command": "java",
      "groupName": "os-group-1",
      "containerImage": "openjdk:11",
      "status": 1
    }
  }'

Response:

{
  "status": "OK",
  "commandPrefixImageMapping": {
    "id": 2,
    "command": "java",
    "groupName": "os-group-1",
    "containerImage": "openjdk:11",
    "status": 1
  }
}

Result: PASS


22. POST /jobType

curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobType' \
  -H 'Content-Type: application/json' \
  -d '{
    "jobType": {
      "name": "CustomType",
      "groupName": "os-group-1",
      "containerImage": "custom-image:latest",
      "monitoringTags": "{\"FAILED_JOBS\": \"sev4\"}",
      "status": 1
    }
  }'

Response:

{
  "status": "OK",
  "jobType": {
    "id": 2,
    "name": "CustomType",
    "groupName": "os-group-1",
    "containerImage": "custom-image:latest",
    "monitoringTags": "{\"FAILED_JOBS\": \"sev4\"}",
    "status": 1
  }
}

Result: PASS

Note: monitoringTags must be a JSON string (escaped), not a raw JSON object.


23. POST /jobDetail

curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobDetail' \
  -H 'Content-Type: application/json' \
  -d '{
    "jobDetail": {
      "jobDetailId": 1,
      "priority": 2,
      "retryPeriod": 120
    }
  }'

Response:

{
  "status": "OK",
  "jobDetail": {
    "jobDetailId": 1,
    "priority": 2,
    "retryPeriod": 120
  }
}

Result: PASS


24. POST /job (useArgoWorkflows: false)

curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/job' \
  -H 'Content-Type: application/json' \
  -H 'os-scheduling-group: os-group-1' \
  -d '{
    "job": {
      "jobName": "testJob1",
      "applicationName": "testApp1",
      "command": "echo hello",
      "jobTypeName": "Default",
      "useArgoWorkflows": false
    }
  }'

Response:

{
  "status": "OK",
  "job": {
    "jobId": 3,
    "jobName": "testJob1",
    "applicationName": "testApp1",
    "status": "SUBMITTED"
  }
}

Result: PASS

Creates 3 DB entries: job_details, jobs, job_triggers. No Kafka event published.


25. POST /job (useArgoWorkflows: true) — Kafka Flow

curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/job' \
  -H 'Content-Type: application/json' \
  -H 'os-scheduling-group: os-group-1' \
  -d '{
    "job": {
      "jobName": "argoJob1",
      "applicationName": "testApp1",
      "command": "echo argo",
      "jobTypeName": "Default",
      "useArgoWorkflows": true
    }
  }'

Response:

{
  "status": "OK",
  "job": {
    "jobId": 6,
    "jobName": "argoJob1",
    "applicationName": "testApp1",
    "status": "SUBMITTED"
  }
}

Scheduler Logs (confirmed):

ArgoEventSender: Sending event for job 6 | eventType: argo_ondemand_cluster_1 | eventName: ARGO_JOB_SUBMISSION
ArgoEventSender: Successfully posted event for job: 6

Result: PASS

Full flow: POST /jobArgoEventSenderEventManager → Kafka (GCP_KAFKA) Requires PROD_KAFKA_TOPIC_VERSION_SETTING in property-settings DB.


POST-Only Endpoints (No GET)

Endpoint GET POST Reason
/job Not supported (500) PASS initServletObjectMap(null, JobPostRequest.class, ...)
/jobStat Not supported (500) PASS initServletObjectMap(null, JobStatPostRequest.class, ...)

Summary

Test Results

# Endpoint Method Result
1 /cluster?id=1 GET PASS
2 /cluster?name=Cluster 1 GET PASS
3 /group?id=1 GET PASS
4 /group?groupName=os-group-1 GET PASS
5 /jobTrigger?id=1 GET PASS
6 /jobTrigger?jobName=TestJob GET PASS
7 /schedules?id=1 GET PASS
8 /jobDetail?jobDetailId=1 GET PASS
9 /jobType?groupName=...&name=... GET PASS
10 /tags?id=1&groupId=1 GET PASS
11 /commandPrefixImageMapping GET PASS
12 /containerImageVersionTag GET PASS
13 /schedulesMetadata GET PASS
14 /group POST PASS
15 /schedules POST PASS
16 /jobTrigger POST PASS
17 /jobStat POST PASS
18 /tags POST PASS
19 /containerImageVersionTag POST PASS
20 /schedulesMetadata POST PASS
21 /commandPrefixImageMapping POST PASS
22 /jobType POST PASS
23 /jobDetail POST PASS
24 /job (useArgoWorkflows: false) POST PASS
25 /job (useArgoWorkflows: true) POST PASS

Total: 25/25 PASS

Key Findings

  • 13 GET endpoints all working with correct query parameters
  • 9 POST endpoints all working with correct JSON body format
  • 2 POST-only endpoints (/job, /jobStat) — GET returns 500 by design
  • Kafka flow verifieduseArgoWorkflows: true publishes events via EventManager to Kafka
  • Event type: argo_ondemand_cluster_1, Event name: ARGO_JOB_SUBMISSION
  • Application: osOnDemandJobsArgoRunner

Dependencies Verified

Dependency Status Notes
MySQL (os_scheduling_db) Working Via Hibernate XML, no Hades needed
Event-Manager-V2 Working Receives Argo events from scheduler
Property-Settings-V2 Working Provides PROD_KAFKA_TOPIC_VERSION_SETTING
Kafka Working Receives events via GCP_KAFKA path
Hades Not needed Scheduler uses direct Hibernate connection