Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix to better handle lambda responses when they are empty or null or not a valid json #5211

Merged
merged 15 commits into from
Nov 22, 2024

Conversation

san81
Copy link
Collaborator

@san81 san81 commented Nov 21, 2024

Description

In the cases where the Lambda response is not a proper Json, we are better handling the logic now as described below

Issues Resolved

Resolves #[Issue number to be closed when this PR is merged]

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.

…not a valid json

Signed-off-by: Santhosh Gandhe <1909520+san81@users.noreply.github.com>
Signed-off-by: Santhosh Gandhe <1909520+san81@users.noreply.github.com>
Signed-off-by: Santhosh Gandhe <1909520+san81@users.noreply.github.com>
Signed-off-by: Santhosh Gandhe <1909520+san81@users.noreply.github.com>
@@ -72,6 +73,7 @@ public class LambdaProcessor extends AbstractProcessor<Record<Event>, Record<Eve
private final Counter numberOfRecordsFailedCounter;
private final Counter numberOfRequestsSuccessCounter;
private final Counter numberOfRequestsFailedCounter;
private final Counter lambdaResponseRecordsCounter;
Copy link
Member

Choose a reason for hiding this comment

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

Should we use a DistributionSummary here? This will let us both count and understand the sizes per request.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@dlvenable let's do this in the follow up PR

"Lambda response payload is null or empty, dropping the original events");
return responseStrategy.handleEvents(parsedEvents, originalRecords);
// Considering "null" payload as empty response from lambda and not parsing it.
if (!("null".equals(payload.asUtf8String()))) {
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain the "null" string situation?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Like then Lambda response is a plain one word "null" then we are considering it as empty response and not trying to parse it. It is basically like no response from lambda so we are going to drop all the records in the case of AggregateMode but fail in the case of StrictMode

Copy link
Member

Choose a reason for hiding this comment

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

Is this a Lambda response or a response from the Lambda function?

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is lambda response.

Copy link
Member

Choose a reason for hiding this comment

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

Let's make this a constant with a useful name.

e.g.

private static final NO_RETURN_RESPONSE = "null"

assertThrows(RuntimeException.class, () -> localLambdaProcessor.convertLambdaResponseToEvent(buffer, invokeResponse),
"For Strict mode request and response size from lambda should match");

if (null != expectedException) {
Copy link
Member

Choose a reason for hiding this comment

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

It's better not to have conditionals in tests. This can be flaky and hard to understand.

Can we split this into two tests with two different ArgumentsSources methods/providers?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh in this case, it is basically like, is there an exception to assert or no. The check is only based on the arguments but not based on the logic. I think we do have such pattern else where.

Copy link
Member

Choose a reason for hiding this comment

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

I think it is a pattern best avoided.

Copy link
Member

Choose a reason for hiding this comment

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

But, we can keep for now.

san81 and others added 3 commits November 21, 2024 15:28
Signed-off-by: Santhosh Gandhe <1909520+san81@users.noreply.github.com>
Signed-off-by: Santhosh Gandhe <1909520+san81@users.noreply.github.com>
Signed-off-by: Srikanth Govindarajan <srigovs@amazon.com>
lambdaRegion = System.getProperty("tests.lambda.processor.region");
functionName = System.getProperty("tests.lambda.processor.functionName");
role = System.getProperty("tests.lambda.processor.sts_role_arn");
// lambdaRegion = System.getProperty("tests.lambda.processor.region");
Copy link
Member

Choose a reason for hiding this comment

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

I think you meant to revert this comment. This will not work in our CI.

"Lambda response payload is null or empty, dropping the original events");
return responseStrategy.handleEvents(parsedEvents, originalRecords);
// Considering "null" payload as empty response from lambda and not parsing it.
if (!("null".equals(payload.asUtf8String()))) {
Copy link
Member

Choose a reason for hiding this comment

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

Is this a Lambda response or a response from the Lambda function?

san81 and others added 6 commits November 21, 2024 16:24
Signed-off-by: Santhosh Gandhe <1909520+san81@users.noreply.github.com>
Signed-off-by: Srikanth Govindarajan <srigovs@amazon.com>
Signed-off-by: Santhosh Gandhe <1909520+san81@users.noreply.github.com>
Signed-off-by: Srikanth Govindarajan <srigovs@amazon.com>
@san81 san81 marked this pull request as ready for review November 22, 2024 01:05
Signed-off-by: Srikanth Govindarajan <srigovs@amazon.com>
arguments("lambda-processor-success-config.yaml", thirdSample, "random string",thirdSample, true),
arguments("lambda-processor-success-config.yaml", fourthSample, SdkBytes.fromByteArray("[]".getBytes()), fourthSample, true),
arguments("lambda-processor-success-config.yaml", fifthSample, SdkBytes.fromByteArray(fifthSampleJsonString.getBytes()), fifthSample, false)/*,
arguments("lambda-processor-success-config.yaml", getSampleEventRecords(1), SdkBytes.fromByteArray("[{\"key\":\"val\"}, {\"key\":\"val\"}]".getBytes()),Collections.emptyList()),
Copy link
Member

Choose a reason for hiding this comment

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

Please remove commented out code

Copy link
Collaborator

Choose a reason for hiding this comment

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

Removed

assertThrows(RuntimeException.class, () -> localLambdaProcessor.convertLambdaResponseToEvent(buffer, invokeResponse),
"For Strict mode request and response size from lambda should match");

if (null != expectedException) {
Copy link
Member

Choose a reason for hiding this comment

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

I think it is a pattern best avoided.

@@ -73,6 +97,8 @@
import static org.opensearch.dataprepper.plugins.lambda.utils.LambdaTestSetupUtil.getSampleEventRecords;
import static org.opensearch.dataprepper.plugins.lambda.utils.LambdaTestSetupUtil.getSampleRecord;

=======
Copy link
Member

Choose a reason for hiding this comment

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

Merge conflicts

"Lambda response payload is null or empty, dropping the original events");
return responseStrategy.handleEvents(parsedEvents, originalRecords);
// Considering "null" payload as empty response from lambda and not parsing it.
if (!("null".equals(payload.asUtf8String()))) {
Copy link
Member

Choose a reason for hiding this comment

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

Let's make this a constant with a useful name.

e.g.

private static final NO_RETURN_RESPONSE = "null"

throw new RuntimeException(
"Response Processing Mode is configured as Strict mode but behavior is aggregate mode. Event count mismatch.");
throw new StrictResponseModeNotRespectedException(
"Response Processing Mode is configured as Strict mode but behavior is aggregate mode. " +
Copy link
Member

Choose a reason for hiding this comment

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

"The aws_lambda processor is configured with response_events_match set to true. The Lambda function responded with a different number of events. Either set response_events_match to false or investigate your Lambda function to ensure that it returns the same number of events and provided as input. parsedEvents size = . Original events size = "

Signed-off-by: Srikanth Govindarajan <srigovs@amazon.com>
@kkondaka kkondaka merged commit 539d599 into opensearch-project:main Nov 22, 2024
46 of 47 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.

4 participants