Skip to content

Commit

Permalink
Merge pull request #2097 from beyonnex-io/bugfix/entity-id-wrong-format
Browse files Browse the repository at this point in the history
#2096: fix entityId header was added in the wrong format
  • Loading branch information
thjaeckle authored Jan 16, 2025
2 parents d4bf9a8 + 0628ca0 commit a2887f7
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 13 deletions.
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);
}
}

0 comments on commit a2887f7

Please sign in to comment.