Skip to content

Add /ready endpoint to DataPrepperServer for ALB health check readiness gating#6977

Merged
graytaylor0 merged 1 commit into
opensearch-project:mainfrom
Davidding4718:fix/alb-502-readiness-endpoint
Jul 7, 2026
Merged

Add /ready endpoint to DataPrepperServer for ALB health check readiness gating#6977
graytaylor0 merged 1 commit into
opensearch-project:mainfrom
Davidding4718:fix/alb-502-readiness-endpoint

Conversation

@Davidding4718

@Davidding4718 Davidding4718 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Description

Add a /ready readiness endpoint on the admin server (port 4900) that returns 200 OK only after all pipeline sources have started listening, and 503 Service Unavailable while any pipeline source is still initializing.

During auto-scaling events, the existing ALB health check on /list passes as soon as port 4900 starts, but the data ingestion port (e.g. 21890) hasn't started yet. The ALB routes traffic to the target, gets connection refused, and returns a 502 to the customer. This new endpoint enables the ALB health check to be pointed at /ready so targets are only marked healthy once they can actually serve traffic.

Changes:

  • Add volatile boolean sourceStarted flag to Pipeline.java that flips after source.start()
  • Add ReadinessHandler implementing GET /ready that checks isSourceStarted() on all pipelines
  • Wire the handler into DataPrepperServer and Spring configuration

Issues Resolved

NULL

Check List

  • New functionality includes testing.
  • New functionality has a documentation issue. Please link to it in this PR.
    • New functionality has javadoc added
  • Commits are signed with a real name per the DCO

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

return;
}

final boolean allReady = pipelines.values().stream()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be good to just run one test yourself that uses a yaml with one true source like http / otel, and another "pipeline" source.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I have tested locally with following config and added a temporary 30s sleep before source.start() to make the 503 window observable::

entry-pipeline:
  source:
    http:
      port: 21890
      ssl: false
  sink:
    - pipeline:
        name: "downstream-pipeline"

downstream-pipeline:
  source:
    pipeline:
      name: "entry-pipeline"
  sink:
    - stdout:

here is the ingestion result:

13:54:51 - HTTP 503 - {"ready":false,"reason":"pipelines not started: [entry-pipeline, downstream-pipeline]"}
13:54:52 - HTTP 503 - {"ready":false,"reason":"pipelines not started: [entry-pipeline, downstream-pipeline]"}
13:54:53 - HTTP 503 - {"ready":false,"reason":"pipelines not started: [entry-pipeline]"}
...
13:55:23 - HTTP 200 - {"ready":true}

The pipeline source (downstream-pipeline) starts instantly and drops off the 503 list within 1s. The http source (entry-pipeline) stays in 503 until source.start() completes and port 21890 is listening. /ready only returns 200 when all pipelines have their sources started.

.filter(e -> !e.getValue().isSourceStarted())
.map(Map.Entry::getKey)
.collect(Collectors.joining(", "));
LOG.info("Readiness check: pipelines not ready: [{}]", notReady);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably make this a DEBUG log as it will be a little noisy

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call! I changed it to LOG.debug. This will be hit every 30s by the ALB health check so INFO would be too noisy.

…all pipeline sources have started. This prevents ALB from routing traffic to targets before the data ingestion port is listening, eliminating 502 errors during scale-up events.

Signed-off-by: Siqi Ding <dingdd@amazon.com>
@Davidding4718
Davidding4718 force-pushed the fix/alb-502-readiness-endpoint branch from 0ef2937 to 25f6033 Compare July 7, 2026 13:27

@graytaylor0 graytaylor0 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@divbok

divbok commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Looks good!

@graytaylor0
graytaylor0 merged commit e1d1a32 into opensearch-project:main Jul 7, 2026
70 of 72 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants