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

#2096: fix entityId header was added in the wrong format #2097

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ entries:
- title: Release Notes
output: web
folderitems:
- title: 3.6.9
url: /release_notes_369.html
output: web
- title: 3.6.8
url: /release_notes_368.html
output: web
Expand Down
30 changes: 30 additions & 0 deletions documentation/src/main/resources/pages/ditto/release_notes_369.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: Release notes 3.6.9
tags: [release_notes]
published: true
keywords: release notes, announcements, changelog
summary: "Version 3.6.9 of Eclipse Ditto, released on 16.01.2025"
permalink: release_notes_369.html
---

This is a bugfix release, no new features since [3.6.8](release_notes_368.html) were added.

## Changelog

Compared to the latest release [3.6.8](release_notes_368.html), the following changes and bugfixes were added.

### Bugfixes
This is a complete list of the
[merged pull requests](https://github.com/eclipse-ditto/ditto/pulls?q=is%3Apr+milestone%3A3.6.9).

#### Fix exceptions in WebSocket due to wrongly formatted added "EntityId" header

Ditto release [3.6.5](release_notes_365.html) introduced an improved log messages for errors in WoT validations, adding
the Thing's ID to the log message. Internally, a change was needed to always provide the thing's ID as internal header.
This added header had however the wrong format, which caused exceptions e.g. in the Ditto WebSocket handling.

This was reported in issue [#2096](https://github.com/eclipse-ditto/ditto/issues/2096) and was fixed via PR
[#2097](https://github.com/eclipse-ditto/ditto/pull/2097).

As this is a very critical bug, a bugfix release containing just this one fix is provided: `3.6.9`.

Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ protected CompletionStage<Signal<?>> performWotBasedSignalValidation(final Signa
return performWotBasedMessageCommandValidation(messageCommand.setDittoHeaders(
DittoHeaders.of(startedSpan.propagateContext(messageCommand.getDittoHeaders()))
.toBuilder()
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), entityId.toString())
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(),
entityId.getEntityType() + ":" + entityId)
.build()
)).whenComplete((result, error) -> {
if (error instanceof DittoRuntimeException dre) {
Expand Down Expand Up @@ -243,7 +244,8 @@ protected CompletionStage<CommandResponse<?>> performWotBasedResponseValidation(
messageCommandResponse.setDittoHeaders(
DittoHeaders.of(startedSpan.propagateContext(messageCommandResponse.getDittoHeaders()))
.toBuilder()
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), entityId.toString())
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(),
entityId.getEntityType() + ":" + entityId)
.build()
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,9 @@ public Result<ThingEvent<?>> apply(final Context<ThingId> context, @Nullable fin
final long nextRevision, final C command) {

final var dittoHeaders = command.getDittoHeaders();
final ThingId thingId = context.getState();
final var dittoHeadersBuilder = dittoHeaders.toBuilder()
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), context.getState().toString());
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.getEntityType() + ":" + thingId);
final var loggerWithCorrelationId = context.getLog().withCorrelationId(command);
final var thingConditionFailed = dittoHeaders.getCondition()
.flatMap(condition -> ThingConditionValidator.validate(command, condition, entity));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ protected static DittoHeaders appendEntityIdAndETagToDittoHeaders(final ThingId
final DittoHeaders dittoHeaders
) {
return dittoHeaders.toBuilder()
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.toString())
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.getEntityType() + ":" + thingId)
.eTag(EntityTag.fromEntity(object).get())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,9 @@ private EventsourcedEvent<?> sendModifyThing(final Thing modifiedThing, final Ac
modifiedThing, null, dittoHeadersV2);
underTest.tell(modifyThingCommand, getRef());

final ThingId thingId = modifiedThing.getEntityId().get();
expectMsgEquals(modifyThingResponse(modifiedThing, dittoHeadersV2.toBuilder().putHeader(
DittoHeaderDefinition.ENTITY_ID.getKey(), modifiedThing.getEntityId().get().toString())
DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.getEntityType() + ":" + thingId)
.build()
));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void deletedThingIsSnapshotWithCorrectDataAndCanBeRecreated() {
final DeleteThing deleteThing = DeleteThing.of(thingId, dittoHeadersV2);
underTest.tell(deleteThing, getRef());
expectMsgEquals(DeleteThingResponse.of(thingId, dittoHeadersV2.toBuilder()
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.toString())
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.getEntityType() + ":" + thingId)
.build()));

final Thing expectedDeletedSnapshot = toDeletedThing(2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -595,8 +595,9 @@ public void deleteThingV2() {

final DeleteThing deleteThing = DeleteThing.of(getIdOrThrow(thing), dittoHeadersV2);
underTest.tell(deleteThing, getRef());
final ThingId thingId = thing.getEntityId().get();
expectMsgEquals(DeleteThingResponse.of(getIdOrThrow(thing), dittoHeadersV2.toBuilder()
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thing.getEntityId().get().toString())
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.getEntityType() + ":" + thingId)
.build()));
}
};
Expand All @@ -623,7 +624,7 @@ public void deleteAndRecreateThingWithMinimumData() {
final DeleteThing deleteThing = DeleteThing.of(thingId, dittoHeadersV2);
underTest.tell(deleteThing, getRef());
expectMsgEquals(DeleteThingResponse.of(thingId, dittoHeadersV2.toBuilder()
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.toString())
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.getEntityType() + ":" + thingId)
.build()));

final Thing minimalThing = Thing.newBuilder()
Expand Down Expand Up @@ -839,7 +840,7 @@ public void deleteAttribute() {
final ThingCommand authorizedCommand = DeleteAttribute.of(thingId, attributeKey, dittoHeadersV2);
underTest.tell(authorizedCommand, getRef());
expectMsgEquals(DeleteAttributeResponse.of(thingId, attributeKey, dittoHeadersV2.toBuilder()
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.toString())
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.getEntityType() + ":" + thingId)
.build()));
}
};
Expand All @@ -864,7 +865,7 @@ public void tryToRetrieveThingAfterDeletion() {

underTest.tell(deleteThingCommand, getRef());
expectMsgEquals(DeleteThingResponse.of(thingId, dittoHeadersV2.toBuilder()
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.toString())
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.getEntityType() + ":" + thingId)
.build()));

underTest.tell(retrieveThingCommand, getRef());
Expand Down Expand Up @@ -926,7 +927,7 @@ public void recoverThingDeleted() {
final DeleteThing deleteThing = DeleteThing.of(thingId, dittoHeadersV2);
underTest.tell(deleteThing, getRef());
expectMsgEquals(DeleteThingResponse.of(thingId, dittoHeadersV2.toBuilder()
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.toString())
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.getEntityType() + ":" + thingId)
.build()));

// restart actor to recover thing state
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,9 @@ protected static <C extends Command<?>> void assertUnhandledResult(
}

protected static DittoHeaders provideHeaders(final CommandStrategy.Context<ThingId> context) {
final ThingId thingId = context.getState();
return DittoHeaders.newBuilder()
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), context.getState().toString())
.putHeader(DittoHeaderDefinition.ENTITY_ID.getKey(), thingId.getEntityType() + ":" + thingId)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ public static ValidationContext buildValidationContext(final DittoHeaders dittoH
}

private static Optional<ThingId> extractThingId(final DittoHeaders dittoHeaders) {
return Optional.ofNullable(dittoHeaders.get(DittoHeaderDefinition.ENTITY_ID.getKey()))
final String nullableEntityId = dittoHeaders.get(DittoHeaderDefinition.ENTITY_ID.getKey());
return Optional.ofNullable(nullableEntityId)
.map(entityId -> entityId.substring(entityId.indexOf(":") + 1)) // starts with "thing:" - cut that off!
.map(ThingId::of);
}
}
Loading