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

Properly handle events without the data field #1460

Conversation

pierDipi
Copy link
Member

A valid CloudEvent in the CE binary protocol binding of Kafka
might be composed by only Headers.

KafkaConsumer doesn't call the deserializer if the value
is null.

That means that we get a record with a null value even though
the record is a valid CloudEvent.

This patch handles events without the data field properly
by creating the CloudEvent object from record headers, if
the above conditions apply.

Fixes #1455

Proposed Changes

  • Properly handle events without data field

Release Note

Properly handle events without the `data` field.

Docs

None

@google-cla google-cla bot added the cla: yes Indicates the PR's author has signed the CLA. label Nov 10, 2021
@knative-prow-robot knative-prow-robot added area/data-plane size/L Denotes a PR that changes 100-499 lines, ignoring generated files. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Nov 10, 2021
@pierDipi
Copy link
Member Author

/cherry-pick release-1.0

@knative-prow-robot
Copy link
Contributor

@pierDipi: once the present PR merges, I will cherry-pick it on top of release-1.0 in a new PR and assign it to you.

In response to this:

/cherry-pick release-1.0

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@pierDipi
Copy link
Member Author

/cherry-pick release-0.26

@knative-prow-robot
Copy link
Contributor

@pierDipi: once the present PR merges, I will cherry-pick it on top of release-0.26 in a new PR and assign it to you.

In response to this:

/cherry-pick release-0.26

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@pierDipi
Copy link
Member Author

/cherry-pick release-0.25

@knative-prow-robot
Copy link
Contributor

@pierDipi: once the present PR merges, I will cherry-pick it on top of release-0.25 in a new PR and assign it to you.

In response to this:

/cherry-pick release-0.25

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@pierDipi
Copy link
Member Author

/cherry-pick release-0.26

@knative-prow-robot
Copy link
Contributor

@pierDipi: once the present PR merges, I will cherry-pick it on top of release-0.26 in a new PR and assign it to you.

In response to this:

/cherry-pick release-0.26

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@pierDipi
Copy link
Member Author

/cherry-pick release-1.0

@knative-prow-robot
Copy link
Contributor

@pierDipi: once the present PR merges, I will cherry-pick it on top of release-1.0 in a new PR and assign it to you.

In response to this:

/cherry-pick release-1.0

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@codecov
Copy link

codecov bot commented Nov 10, 2021

Codecov Report

Merging #1460 (6f563e9) into main (d24bcb7) will decrease coverage by 0.03%.
The diff coverage is 81.48%.

Impacted file tree graph

@@             Coverage Diff              @@
##               main    #1460      +/-   ##
============================================
- Coverage     73.41%   73.38%   -0.04%     
- Complexity      575      586      +11     
============================================
  Files           100      102       +2     
  Lines          3942     3986      +44     
  Branches        160      165       +5     
============================================
+ Hits           2894     2925      +31     
- Misses          808      823      +15     
+ Partials        240      238       -2     
Flag Coverage Δ
java-unittests 82.00% <81.48%> (-0.17%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...a/broker/dispatcher/impl/RecordDispatcherImpl.java 78.72% <64.28%> (-3.21%) ⬇️
...er/impl/consumer/InvalidCloudEventInterceptor.java 91.86% <100.00%> (-1.00%) ⬇️
...atcher/impl/consumer/KafkaConsumerRecordUtils.java 100.00% <100.00%> (ø)
...dispatcher/impl/consumer/BaseConsumerVerticle.java 87.50% <0.00%> (-5.61%) ⬇️
...patcher/impl/consumer/OrderedConsumerVerticle.java 87.03% <0.00%> (-3.35%) ⬇️
control-plane/pkg/reconciler/channel/channel.go 29.96% <0.00%> (-0.12%) ⬇️
...lane/pkg/reconciler/base/receiver_condition_set.go 0.00% <0.00%> (ø)
...broker/dispatcher/impl/consumer/OffsetManager.java 100.00% <0.00%> (ø)
...receiver/impl/handler/MethodNotAllowedHandler.java 100.00% <0.00%> (ø)
...ver/impl/handler/ControlPlaneProbeRequestUtil.java 100.00% <0.00%> (ø)
... and 3 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d24bcb7...6f563e9. Read the comment docs.

A valid CloudEvent in the CE binary protocol binding of Kafka
might be composed by only Headers.

KafkaConsumer doesn't call the deserializer if the value
is null.

That means that we get a record with a null value even though
the record is a valid CloudEvent.

This patch handles events without the data field properly
by creating the CloudEvent object from record headers, if
the above conditions apply.

Signed-off-by: Pierangelo Di Pilato <pdipilat@redhat.com>
@pierDipi pierDipi force-pushed the KNATIVE-1455_NPE-event-no-data branch from aca7c28 to 8267d11 Compare November 10, 2021 18:22
@pierDipi
Copy link
Member Author

GH action failure could be ignored (ref: actions/checkout#273)

Run actions/checkout@v2
Syncing repository: knative-sandbox/eventing-kafka-broker
Getting Git version info
Deleting the contents of '/home/runner/work/eventing-kafka-broker/eventing-kafka-broker'
Error: stderr maxBuffer length exceeded

@pierDipi pierDipi added the kind/bug Categorizes issue or PR as related to a bug. label Nov 11, 2021
@pierDipi
Copy link
Member Author

cc @matzew @aliok can you please take a look at this PR?

Comment on lines 200 to 213
// A valid CloudEvent in the CE binary protocol binding of Kafka
// might be composed by only Headers.
//
// KafkaConsumer doesn't call the deserializer if the value
// is null.
//
// That means that we get a record with a null value event though
// the record is a valid CloudEvent.
if (record.value() == null) {
logDebug("Value is null", record);
final var value = cloudEventDeserializer.deserialize(record.record().topic(), record.record().headers(), null);
return new KafkaConsumerRecordImpl<>(KafkaConsumerRecordUtils.copyRecordAssigningValue(record.record(), value));
}
return record;
Copy link
Contributor

Choose a reason for hiding this comment

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

buildCloudEventValueIfMissing

aren't we here "building" (deserializing) the value of the KafkaConsumerRecord, that happens to be a CloudEvent?

Could we change to if (record.value() != null) { return record; } else { ....} ? Not sure, but that might be easier to read

deserialize(record.record().topic(), record.record().headers(), null); I understand why we pass in null, but.... where is else is the deserialization done? why is it here again invoked, just b/c it is null 🤷‍♂️

Copy link
Member Author

Choose a reason for hiding this comment

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

Could we change to if (record.value() != null) { return record; } else { ....} ? Not sure, but that might be easier to read

I agree!

deserialize(record.record().topic(), record.record().headers(), null); I understand why we pass in null, but.... where is else is the deserialization done? why is it here again invoked, just b/c it is null

The deserialization is done inside the KafkaConsumer, but when value == null, it doesn't call the deserializer since there is nothing to deserialize, so we need to deserialize the record manually when this happens since only record headers constitute a valid CloudEvent.

Copy link
Contributor

Choose a reason for hiding this comment

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

but when value == null, it doesn't call the deserializer

so that's OK for pure/vanilla kafka - but is that a problem for other "protocols" on top? Or is that just a corner-case here 🤷‍♂️

we need to deserialize the record manually when this happens since only record headers constitute a valid CloudEvent.

I just wonder how to make this more obvious - I understand we do it... perhaps the buildCloudEventValueIfMissing name is also not perfect ? 🙈 Sorry, just trying to make it "simpler"

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry, just trying to make it "simpler"

Nah, we're doing code review for this reason, right? 😍

I changed the name to maybeDeserializeValueFromHeaders and changed the if .. as suggested.

Signed-off-by: Pierangelo Di Pilato <pdipilat@redhat.com>
@pierDipi pierDipi force-pushed the KNATIVE-1455_NPE-event-no-data branch from 9e46b72 to 6f563e9 Compare November 17, 2021 12:15
@matzew
Copy link
Contributor

matzew commented Nov 17, 2021 via email

@knative-prow-robot knative-prow-robot added the lgtm Indicates that a PR is ready to be merged. label Nov 17, 2021
@knative-prow-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: matzew, pierDipi

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@knative-prow-robot knative-prow-robot merged commit f04a70f into knative-extensions:main Nov 17, 2021
@knative-prow-robot
Copy link
Contributor

@pierDipi: #1460 failed to apply on top of branch "release-0.26":

Applying: Properly handle events without data field
Using index info to reconstruct a base tree...
M	data-plane/dispatcher/src/main/java/dev/knative/eventing/kafka/broker/dispatcher/impl/RecordDispatcherImpl.java
A	data-plane/dispatcher/src/main/java/dev/knative/eventing/kafka/broker/dispatcher/impl/consumer/InvalidCloudEventInterceptor.java
M	data-plane/tests/src/test/java/dev/knative/eventing/kafka/broker/tests/DataPlaneTest.java
Falling back to patching base and 3-way merge...
Auto-merging data-plane/tests/src/test/java/dev/knative/eventing/kafka/broker/tests/DataPlaneTest.java
CONFLICT (modify/delete): data-plane/dispatcher/src/main/java/dev/knative/eventing/kafka/broker/dispatcher/impl/consumer/InvalidCloudEventInterceptor.java deleted in HEAD and modified in Properly handle events without data field. Version Properly handle events without data field of data-plane/dispatcher/src/main/java/dev/knative/eventing/kafka/broker/dispatcher/impl/consumer/InvalidCloudEventInterceptor.java left in tree.
Auto-merging data-plane/dispatcher/src/main/java/dev/knative/eventing/kafka/broker/dispatcher/impl/RecordDispatcherImpl.java
CONFLICT (content): Merge conflict in data-plane/dispatcher/src/main/java/dev/knative/eventing/kafka/broker/dispatcher/impl/RecordDispatcherImpl.java
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 Properly handle events without data field
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

In response to this:

/cherry-pick release-0.26

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@knative-prow-robot
Copy link
Contributor

@pierDipi: #1460 failed to apply on top of branch "release-0.25":

Applying: Properly handle events without data field
Using index info to reconstruct a base tree...
M	data-plane/dispatcher/src/main/java/dev/knative/eventing/kafka/broker/dispatcher/impl/RecordDispatcherImpl.java
A	data-plane/dispatcher/src/main/java/dev/knative/eventing/kafka/broker/dispatcher/impl/consumer/InvalidCloudEventInterceptor.java
M	data-plane/tests/src/test/java/dev/knative/eventing/kafka/broker/tests/DataPlaneTest.java
Falling back to patching base and 3-way merge...
Auto-merging data-plane/tests/src/test/java/dev/knative/eventing/kafka/broker/tests/DataPlaneTest.java
CONFLICT (modify/delete): data-plane/dispatcher/src/main/java/dev/knative/eventing/kafka/broker/dispatcher/impl/consumer/InvalidCloudEventInterceptor.java deleted in HEAD and modified in Properly handle events without data field. Version Properly handle events without data field of data-plane/dispatcher/src/main/java/dev/knative/eventing/kafka/broker/dispatcher/impl/consumer/InvalidCloudEventInterceptor.java left in tree.
Auto-merging data-plane/dispatcher/src/main/java/dev/knative/eventing/kafka/broker/dispatcher/impl/RecordDispatcherImpl.java
CONFLICT (content): Merge conflict in data-plane/dispatcher/src/main/java/dev/knative/eventing/kafka/broker/dispatcher/impl/RecordDispatcherImpl.java
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 Properly handle events without data field
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

In response to this:

/cherry-pick release-0.25

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@knative-prow-robot
Copy link
Contributor

@pierDipi: new pull request created: #1500

In response to this:

/cherry-pick release-1.0

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@pierDipi pierDipi deleted the KNATIVE-1455_NPE-event-no-data branch November 17, 2021 13:16
pierDipi added a commit to pierDipi/eventing-kafka-broker that referenced this pull request Nov 17, 2021
)

A valid CloudEvent in the CE binary protocol binding of Kafka
might be composed by only Headers.

KafkaConsumer doesn't call the deserializer if the value
is null.

That means that we get a record with a null value even though
the record is a valid CloudEvent.

This patch handles events without the data field properly
by creating the CloudEvent object from record headers, if
the above conditions apply.

Signed-off-by: Pierangelo Di Pilato <pdipilat@redhat.com>
knative-prow-robot pushed a commit that referenced this pull request Nov 17, 2021
A valid CloudEvent in the CE binary protocol binding of Kafka
might be composed by only Headers.

KafkaConsumer doesn't call the deserializer if the value
is null.

That means that we get a record with a null value even though
the record is a valid CloudEvent.

This patch handles events without the data field properly
by creating the CloudEvent object from record headers, if
the above conditions apply.

Signed-off-by: Pierangelo Di Pilato <pdipilat@redhat.com>
knative-prow-robot pushed a commit to knative-prow-robot/eventing-kafka-broker that referenced this pull request Nov 17, 2021
)

A valid CloudEvent in the CE binary protocol binding of Kafka
might be composed by only Headers.

KafkaConsumer doesn't call the deserializer if the value
is null.

That means that we get a record with a null value even though
the record is a valid CloudEvent.

This patch handles events without the data field properly
by creating the CloudEvent object from record headers, if
the above conditions apply.

Signed-off-by: Pierangelo Di Pilato <pdipilat@redhat.com>
pierDipi added a commit to pierDipi/eventing-kafka-broker that referenced this pull request Nov 17, 2021
) (knative-extensions#1502)

A valid CloudEvent in the CE binary protocol binding of Kafka
might be composed by only Headers.

KafkaConsumer doesn't call the deserializer if the value
is null.

That means that we get a record with a null value even though
the record is a valid CloudEvent.

This patch handles events without the data field properly
by creating the CloudEvent object from record headers, if
the above conditions apply.

Signed-off-by: Pierangelo Di Pilato <pdipilat@redhat.com>
knative-prow-robot added a commit that referenced this pull request Nov 17, 2021
A valid CloudEvent in the CE binary protocol binding of Kafka
might be composed by only Headers.

KafkaConsumer doesn't call the deserializer if the value
is null.

That means that we get a record with a null value even though
the record is a valid CloudEvent.

This patch handles events without the data field properly
by creating the CloudEvent object from record headers, if
the above conditions apply.

Signed-off-by: Pierangelo Di Pilato <pdipilat@redhat.com>

Co-authored-by: Pierangelo Di Pilato <pdipilat@redhat.com>
openshift-merge-robot pushed a commit to openshift-knative/eventing-kafka-broker that referenced this pull request Nov 17, 2021
) (knative-extensions#1502) (#39)

A valid CloudEvent in the CE binary protocol binding of Kafka
might be composed by only Headers.

KafkaConsumer doesn't call the deserializer if the value
is null.

That means that we get a record with a null value even though
the record is a valid CloudEvent.

This patch handles events without the data field properly
by creating the CloudEvent object from record headers, if
the above conditions apply.

Signed-off-by: Pierangelo Di Pilato <pdipilat@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/data-plane cla: yes Indicates the PR's author has signed the CLA. kind/bug Categorizes issue or PR as related to a bug. lgtm Indicates that a PR is ready to be merged. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Filtering an empty event results in a NullPointerException
3 participants