Skip to content

Use SdkClient for persistence in 4 transport actions#2060

Merged
engechas merged 2 commits intoopensearch-project:remote-metadata-supportfrom
manaswini1920:feature/sdk-persistence-batch2
Apr 2, 2026
Merged

Use SdkClient for persistence in 4 transport actions#2060
engechas merged 2 commits intoopensearch-project:remote-metadata-supportfrom
manaswini1920:feature/sdk-persistence-batch2

Conversation

@manaswini1920
Copy link
Copy Markdown
Contributor

Description

Use SdkClient for persistence in 4 transport actions:

  • TransportDeleteMonitorAction: sdkClient.getDataObject() in getMonitor()
  • TransportSearchMonitorAction: sdkClient.searchDataObjectAsync() in search()
  • TransportGetDestinationsAction: sdkClient.searchDataObjectAsync() in search()
  • TransportSearchAlertingCommentAction: sdkClient.searchDataObjectAsync() in search()

Walk full cause chain for IndexNotFoundException handling.
Add unit tests for SearchMonitor and GetDestinations SDK paths.

Related Issues

Follows pattern from #2053

Check List

  • New functionality includes testing.
  • Commits are signed per the DCO using --signoff.

@manaswini1920 manaswini1920 changed the base branch from main to remote-metadata-support March 26, 2026 18:54
@manaswini1920 manaswini1920 force-pushed the feature/sdk-persistence-batch2 branch from 64ca2df to ec7c4c7 Compare March 26, 2026 18:55
Copy link
Copy Markdown
Member

@eirsep eirsep left a comment

Choose a reason for hiding this comment

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

we need to ensure we finish loop after listener.onResponse/Failure statements.

and transversely we need to make sure listener.onResponse/Failure statements. is present everywhere

we have had a lot of pain with this in past ... plz add unit tests with 100% coverage for action classes.

rest changes are LGTM

@manaswini1920
Copy link
Copy Markdown
Contributor Author

we need to ensure we finish loop after listener.onResponse/Failure statements.

and transversely we need to make sure listener.onResponse/Failure statements. is present everywhere

we have had a lot of pain with this in past ... plz add unit tests with 100% coverage for action classes.

rest changes are LGTM

Fixed both issues:

  1. getMonitor() — changed actionListener.onFailure() without return to throw, which is caught by the caller's try/catch. This also prevents the NPE on getResponse!! that would have occurred when falling through.
  2. resolveUserAndStart() — added explicit return after onFailure for the workflow delegate check.
    │ Audited all 4 actions — SearchMonitor, GetDestinations, and SearchComments already

Added more unit tests for coverage in the next revision.

@manaswini1920 manaswini1920 force-pushed the feature/sdk-persistence-batch2 branch 2 times, most recently from 16e447d to 5b2292b Compare March 28, 2026 03:41
Comment on lines -125 to -126
actionListener.onFailure(
AlertingException.wrap(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we no longer need to notify the action listener or wrap the exception type as alerting with the remote SDK?

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.

We still do — getMonitor() throws on failure, which is caught by resolveUserAndStart()'s catch block (L116) where actionListener.onFailure(AlertingException.wrap(t)) is called. The previous code called
onFailure directly in getMonitor() but didn't return after, causing an NPE on the next line. Moving to throw/catch fixes that while keeping the same listener notification and AlertingException wrapping.

}
try {
val searchResponse = response.searchResponse()
if (searchResponse == null) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

When would the search response be null? Wondering if this should be an error case rather than defaulting to an empty list

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.

SDK's SearchDataObjectResponse.searchResponse() returns nullable. It can be null if the SDK fails to deserialize the response from the storage backend. Returning empty is defensive. Happy to change to an error if you think that's better for debugging.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Got it - that sounds like an error case to me but we can reevaluate later

Given it's just a list of destinations it should be fine to have an empty list for now


private suspend fun getMonitor(): Monitor {
val getRequest = GetRequest(ScheduledJob.SCHEDULED_JOBS_INDEX, monitorId)
val tenantId = client.threadPool().threadContext.getHeader(AlertingPlugin.TENANT_ID_HEADER)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What is the behavior if this header is not present?

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.

If the header is absent, tenantId is null. In local mode, multi-tenancy is disabled in the SDK, so null tenantId is fine — no tenant filtering is applied. In remote mode, the upstream service always sets the
x-tenant-id header, so it's never absent. If it were absent with multi-tenancy enabled, the SDK would reject the request with a 400 error

…ons, SearchComments

Replace direct client.get/search calls with sdkClient equivalents:
- TransportDeleteMonitorAction: sdkClient.getDataObject() in getMonitor()
- TransportSearchMonitorAction: sdkClient.searchDataObjectAsync() in search()
- TransportGetDestinationsAction: sdkClient.searchDataObjectAsync() in search()
- TransportSearchAlertingCommentAction: sdkClient.searchDataObjectAsync() in search()

Walk full cause chain for IndexNotFoundException handling.
Add unit tests for SearchMonitor and GetDestinations SDK paths.

Signed-off-by: Manaswini Ragamouni <ragamanu@amazon.com>
@manaswini1920 manaswini1920 force-pushed the feature/sdk-persistence-batch2 branch from 5b2292b to 0cce1e4 Compare March 30, 2026 23:10
@manaswini1920 manaswini1920 force-pushed the feature/sdk-persistence-batch2 branch from a988701 to f4e8ee5 Compare April 2, 2026 18:07
Signed-off-by: Manaswini Ragamouni <ragamanu@amazon.com>
@manaswini1920 manaswini1920 force-pushed the feature/sdk-persistence-batch2 branch from f4e8ee5 to 6800612 Compare April 2, 2026 19:14
}
try {
val searchResponse = response.searchResponse()
if (searchResponse == null) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Got it - that sounds like an error case to me but we can reevaluate later

Given it's just a list of destinations it should be fine to have an empty list for now

@engechas engechas merged commit c622dc4 into opensearch-project:remote-metadata-support Apr 2, 2026
18 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