-
Notifications
You must be signed in to change notification settings - Fork 160
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
Unable to serialize complex (custom) extension in the expected json format #667
Comments
This expected json for extension was working fine with CloudEvent 1.0 , and |
+1 |
1 similar comment
+1 |
In the CloudEvents spec, the type system for metadata https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#type-system describes the type "String" but what you expect is a JSON value ?
Also please, add the full steps to reproduce the issue that I can and paste |
Thanks @pierDipi for responding. Yes, that is the correct expectation (receiving a json value). Below is the code and steps to reproduce the issues while trying both the ways of setting an extension to a
------- Issue 1 --------- @JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Recipient {
@JsonProperty("userid")
private final String userid;
@JsonProperty("clientid")
private final String clientid;
public Recipient(String userid) {
this.userid = userid;
this.clientid = null;
}
@JsonCreator
public Recipient(
@JsonProperty("userid") String userid, @JsonProperty("clientid") String clientid) {
this.userid = userid;
this.clientid = clientid;
}
// ------------------------------------------------------------------------------------------------
// Accessors
// ------------------------------------------------------------------------------------------------
public String getUserid() {
return userid;
}
public String getClientid() {
return clientid;
}
// ------------------------------------------------------------------------------------------------
@Override
public String toString() {
return "Recipient{" + "userid='" + userid + '\'' + ", clientid='" + clientid + '\'' + '}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Recipient recipient = (Recipient) o;
return Objects.equals(userid, recipient.userid) && Objects.equals(clientid, recipient.clientid);
}
@Override
public int hashCode() {
return Objects.hash(userid, clientid);
}
} Creating a custom extension public class RecipientExtension implements CloudEventExtension {
public static final String RECIPIENT_KEY_EXTENSION_NAME = "recipient";
private static final Set<String> KEY_SET = Set.of(RECIPIENT_KEY_EXTENSION_NAME);
private Recipient recipient;
public RecipientExtension(String userId, String clientId) throws IOException {
this.recipient = new Recipient(userId, clientId);
}
public Recipient getRecipient() {
return recipient;
}
@Override
public void readFrom(CloudEventExtensions cloudEventExtensions) {
Object tp = cloudEventExtensions.getExtension(RECIPIENT_KEY_EXTENSION_NAME);
if (tp != null) {
this.recipient = tp instanceof Recipient ? (Recipient) tp : null;
}
}
@Override
public Object getValue(String key) throws IllegalArgumentException {
switch (key) {
case RECIPIENT_KEY_EXTENSION_NAME:
return this.recipient;
default:
throw ExtensionUtils.generateInvalidKeyException(this.getClass(), key);
}
}
@Override
public Set<String> getKeys() {
return KEY_SET;
}
@Override
public String toString() {
return "RecipientExtension{" + "recipient=" + recipient + '}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RecipientExtension that = (RecipientExtension) o;
return Objects.equals(recipient, that.recipient);
}
@Override
public int hashCode() {
return Objects.hash(recipient);
}
} Create the CloudEvent object using private static CloudEvent getCloudEvent()
throws JsonProcessingException {
return CloudEventBuilder.v1()
.withSource(URI.create("some_source"))
.withType("some_event_type")
.withId("some_id")
.withDataContentType("application/json")
.withData(JsonCloudEventData.wrap(convertToJsonNode("some_data")))
.withDataSchema(URI.create("some_schema"))
.withExtension("requestidext", "some_request_id")
.withExtension(new RecipientExtension(userId, null))
.build();
} Now serialize the public static final SimpleModule simpleModule =
getCloudEventJacksonModule(JsonFormatOptions.builder().build());
private static final ObjectMapper OBJECT_MAPPER =
JsonMapper.builder()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.serializationInclusion(Include.NON_NULL)
.addModule(
simpleModule)
.build();
public static String serialize(final CloudEvent object) throws JsonProcessingException {
Preconditions.checkNotNull(object, THE_OBJECT_INSTANCE_CAN_NOT_BE_NULL);
return OBJECT_MAPPER.writeValueAsString(object);
} the above serialization will fail with -------- Issue 2 -------- var recipientExt = new RecipientExtension(userId, clientId); get the .withExtension("recipient", serialize(recipientExt.getRecipient())); |
Hi @pierDipi, is there any update on this? We are blocked with our java17 upgrade due to this. |
creating a custom extension object implementing
CloudEventExtension
, when using the extension (customExt
) as below, and then serializing the CloudEvent, the serialization for the CloudEvent is failing with JsonMappingException.here is how the extension looks like. The
customExt
is theRecipient
objectAlso, if using the other supported methods
withExtension
(with key, value) as below, I had to send the string version of the customExt, and then if serialized the output is not in the expected format (see below). It can break our customers eventintegrations. Kindly suggest.
expected serialized CloudEvent custom extension
actual serialized CloudEvent custom extension
The serialization is failing while reading extensions here, as I believe the
Object
typevalue
is not supported.The text was updated successfully, but these errors were encountered: