Skip to content

Honor queue-level DelaySeconds for standard SQS queues#1567

Open
Croway wants to merge 1 commit into
floci-io:mainfrom
Croway:quick-fix/standard-queue-delay-seconds
Open

Honor queue-level DelaySeconds for standard SQS queues#1567
Croway wants to merge 1 commit into
floci-io:mainfrom
Croway:quick-fix/standard-queue-delay-seconds

Conversation

@Croway

@Croway Croway commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Standard SQS queues with a DelaySeconds attribute were not applying the delay to messages sent without an explicit per-message DelaySeconds
  • Root cause: the handler→service API used primitive int (default 0), making it impossible to distinguish "omitted" from "explicit 0"
  • Changed int delaySeconds to Integer delaySeconds across the handler/service chain so null falls back to the queue attribute while Integer(0) overrides it
  • Added tests for both queue-level delay application and explicit zero override

Test plan

  • mvn verify passes all tests including new standard queue delay tests
  • Existing FIFO delay tests still pass
  • Camel Spring Boot SqsDelayedQueueTest passes with the fixed floci image

@hectorvent hectorvent added bug Something isn't working sqs Amazon Simple Queue Service (SQS) labels Jun 25, 2026
@hectorvent

Copy link
Copy Markdown
Collaborator

Nice fix, Federico, and it lines up exactly with how AWS models this. DelaySeconds is a NullableInteger on both SendMessage and the batch entry precisely so the service can tell an omitted value from an explicit 0, so moving from int to Integer is the right root cause fix. The null to queue default, explicit 0 to override behavior matches the docs ("if you don't specify a value, the default value for the queue applies"), and I like that the tests cover both directions and you dropped the stale follow-up comment.

One small thing: in the query handler getIntegerParam swallows a parse error and returns null, so a malformed DelaySeconds like "abc" gets treated as omitted and quietly picks up the queue default, whereas AWS returns a validation error for a non-integer value. Low impact since clients send valid integers, just noting it.

Thanks for tracking this down.

@Croway

Croway commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

good catch, I'll throw an exception in case of NumberFormatException

@Croway Croway force-pushed the quick-fix/standard-queue-delay-seconds branch from cfc8a72 to 9aa0231 Compare July 1, 2026 09:36
@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes standard SQS queues not honoring the queue-level DelaySeconds attribute when messages are sent without an explicit per-message delay. The root cause was that int delaySeconds defaulted to 0, making it impossible to distinguish "omitted" (fall back to queue attribute) from "explicitly 0" (override).

  • SqsService.java: Replaces the ternary queue.isFifo() ? queueDelaySeconds : delaySeconds with a proper null-aware branch — standard queues now fall back to queueDelaySeconds when delaySeconds is null.
  • SqsJsonHandler.java / SqsQueryHandler.java: Each handler adds a new parsing helper (parseOptionalInteger / getIntegerParam) that returns null for a missing parameter and throws AwsException for a non-integer value, aligning validation symmetrically across both protocol paths.
  • SqsServiceTest.java: Two new unit tests cover queue-level delay application and explicit-zero override for standard queues.

Confidence Score: 5/5

Safe to merge — the change is narrow, both protocol paths are updated symmetrically, and the new null-aware logic is covered by unit tests.

The int → Integer change threads through all four sendMessage overloads and both handler layers without altering existing behavior. FIFO behavior is unchanged. The new parsing helpers are symmetric across both protocol paths and both throw on non-integer input. Two unit tests confirm the queue-level fallback and explicit-zero override. No wire-format, config, or storage changes.

No files require special attention.

Important Files Changed

Filename Overview
src/main/java/io/github/hectorvent/floci/services/sqs/SqsService.java Core fix: int delaySecondsInteger delaySeconds across all four sendMessage overloads; null-aware delay resolution added for standard queues while preserving existing FIFO override behavior.
src/main/java/io/github/hectorvent/floci/services/sqs/SqsJsonHandler.java Adds parseOptionalInteger helper with isIntegralNumber() guard; both SendMessage and SendMessageBatch paths now return null for absent DelaySeconds and reject non-integer values with AwsException.
src/main/java/io/github/hectorvent/floci/services/sqs/SqsQueryHandler.java Adds getIntegerParam returning null for absent params and throwing for non-integer strings; symmetric with the JSON path's validation behavior.
src/test/java/io/github/hectorvent/floci/services/sqs/SqsServiceTest.java Two new tests: queueLevelDelaySecondsAppliesToStandardQueue (time-based, 1-second queue delay) and explicitZeroDelayOverridesQueueDefault (immediate receipt after explicit 0 override).

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Client
    participant Handler as SqsJsonHandler / SqsQueryHandler
    participant Service as SqsService

    Client->>Handler: SendMessage(QueueUrl, MessageBody, [DelaySeconds?])

    alt DelaySeconds absent
        Handler->>Handler: parseOptionalInteger / getIntegerParam → null
    else "DelaySeconds = 0"
        Handler->>Handler: parseOptionalInteger / getIntegerParam → Integer(0)
    else "DelaySeconds = 30"
        Handler->>Handler: parseOptionalInteger / getIntegerParam → Integer(30)
    else "DelaySeconds = abc"
        Handler-->>Client: AwsException InvalidParameterValue (400)
    end

    Handler->>Service: sendMessage(url, body, Integer delaySeconds, ...)

    Service->>Service: "queueDelaySeconds = queue.getAttributes(DelaySeconds)"

    alt FIFO queue
        Service->>Service: "effectiveDelay = queueDelaySeconds"
    else "Standard queue + delaySeconds == null"
        Service->>Service: "effectiveDelay = queueDelaySeconds"
    else "Standard queue + delaySeconds != null"
        Service->>Service: "effectiveDelay = delaySeconds"
    end

    Service-->>Handler: Message (with correct visibilityDelay)
    Handler-->>Client: SendMessageResponse
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Client
    participant Handler as SqsJsonHandler / SqsQueryHandler
    participant Service as SqsService

    Client->>Handler: SendMessage(QueueUrl, MessageBody, [DelaySeconds?])

    alt DelaySeconds absent
        Handler->>Handler: parseOptionalInteger / getIntegerParam → null
    else "DelaySeconds = 0"
        Handler->>Handler: parseOptionalInteger / getIntegerParam → Integer(0)
    else "DelaySeconds = 30"
        Handler->>Handler: parseOptionalInteger / getIntegerParam → Integer(30)
    else "DelaySeconds = abc"
        Handler-->>Client: AwsException InvalidParameterValue (400)
    end

    Handler->>Service: sendMessage(url, body, Integer delaySeconds, ...)

    Service->>Service: "queueDelaySeconds = queue.getAttributes(DelaySeconds)"

    alt FIFO queue
        Service->>Service: "effectiveDelay = queueDelaySeconds"
    else "Standard queue + delaySeconds == null"
        Service->>Service: "effectiveDelay = queueDelaySeconds"
    else "Standard queue + delaySeconds != null"
        Service->>Service: "effectiveDelay = delaySeconds"
    end

    Service-->>Handler: Message (with correct visibilityDelay)
    Handler-->>Client: SendMessageResponse
Loading

Reviews (2): Last reviewed commit: "fix: honor queue-level DelaySeconds for ..." | Re-trigger Greptile

Comment thread src/main/java/io/github/hectorvent/floci/services/sqs/SqsJsonHandler.java Outdated
@hectorvent

Copy link
Copy Markdown
Collaborator

Thanks @Croway, could you please take a look at the greptile-apps comments?

@Croway Croway force-pushed the quick-fix/standard-queue-delay-seconds branch from 9aa0231 to 2040eb1 Compare July 2, 2026 09:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working sqs Amazon Simple Queue Service (SQS) waiting-contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants