From 28e29300b8552188f688c2eb3ff4b32a3d101915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20J=C3=A4ckle?= Date: Mon, 10 Feb 2025 16:47:39 +0100 Subject: [PATCH] fix "If-Equal" header predicate for new different from predicate for existing * causing that e.g. the existing Json did not contain "thingId" whereas the new one did --- .../IfEqualPreconditionHeader.java | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/internal/utils/conditional-headers/src/main/java/org/eclipse/ditto/internal/utils/headers/conditional/IfEqualPreconditionHeader.java b/internal/utils/conditional-headers/src/main/java/org/eclipse/ditto/internal/utils/headers/conditional/IfEqualPreconditionHeader.java index 1b1b7f16df..f83d11517d 100644 --- a/internal/utils/conditional-headers/src/main/java/org/eclipse/ditto/internal/utils/headers/conditional/IfEqualPreconditionHeader.java +++ b/internal/utils/conditional-headers/src/main/java/org/eclipse/ditto/internal/utils/headers/conditional/IfEqualPreconditionHeader.java @@ -23,6 +23,8 @@ import javax.annotation.concurrent.Immutable; import org.eclipse.ditto.base.model.entity.Entity; +import org.eclipse.ditto.base.model.entity.id.EntityId; +import org.eclipse.ditto.base.model.entity.type.EntityType; import org.eclipse.ditto.base.model.headers.DittoHeaderDefinition; import org.eclipse.ditto.base.model.headers.IfEqual; import org.eclipse.ditto.base.model.json.FieldType; @@ -52,6 +54,9 @@ public final class IfEqualPreconditionHeader> implements Pr private static final String IF_EQUAL_KEY = DittoHeaderDefinition.IF_EQUAL.getKey(); + private static final EntityType POLICY_ENTITY_TYPE = EntityType.of("policy"); + private static final EntityType THING_ENTITY_TYPE = EntityType.of("thing"); + private final C command; private final IfEqual ifEqual; private final ConditionalHeadersValidator.ValidationSettings validationSettings; @@ -132,14 +137,18 @@ private Boolean meetsConditionForModifyCommand(final Entity entity, return withOptionalEntity.getEntity() .map(newValue -> { - final Predicate fieldPredicate = calculatePredicate(command.getResourcePath()); + final Predicate fieldPredicate = calculatePredicate(command.getResourcePath(), + entity.getEntityId().map(EntityId::getEntityType).orElse(null)); final Optional previousValue = entity.toJson(JsonSchemaVersion.LATEST, fieldPredicate) .getValue(command.getResourcePath()); final JsonValue adjustedNewValue; if (newValue.isObject()) { adjustedNewValue = newValue.asObject() - .filter(calculatePredicateForNew(command.getResourcePath())); + .filter(calculatePredicateForNew( + command.getResourcePath(), + entity.getEntityId().map(EntityId::getEntityType).orElse(null) + )); } else { adjustedNewValue = newValue; } @@ -160,7 +169,10 @@ private Boolean meetsConditionForMergeCommand(final Entity entity, if (command.getResourcePath().isEmpty()) { newObject = newValue.asObject() .stream() - .filter(calculatePredicateForNew(command.getResourcePath())) + .filter(calculatePredicateForNew( + command.getResourcePath(), + entity.getEntityId().map(EntityId::getEntityType).orElse(null) + )) .collect(JsonCollectors.fieldsToObject()); } else { newObject = newValue.asObject(); @@ -240,7 +252,8 @@ private C adjustMergeCommandByOnlyKeepingChanges(final C command, return withOptionalEntity.getEntity() .map(newValue -> { - final Predicate fieldPredicate = calculatePredicate(command.getResourcePath()); + final Predicate fieldPredicate = calculatePredicate(command.getResourcePath(), + entity.getEntityId().map(EntityId::getEntityType).orElse(null)); final JsonValue oldValue = entity.toJson(JsonSchemaVersion.LATEST, fieldPredicate) .getValue(command.getResourcePath()).orElse(null); if (null == oldValue) { @@ -259,22 +272,31 @@ private C adjustMergeCommandByOnlyKeepingChanges(final C command, .orElse(command); } - private static Predicate calculatePredicate(final JsonPointer resourcePath) { + private static Predicate calculatePredicate(final JsonPointer resourcePath, + @Nullable final EntityType entityType + ) { if (resourcePath.isEmpty()) { return FieldType.notHidden() - .and(Predicate.not(jsonField -> jsonField.getKey().equals(JsonKey.of("thingId")))) - .and(Predicate.not(jsonField -> jsonField.getKey().equals(JsonKey.of("policyId")))); + .and(Predicate.not(jsonField -> + THING_ENTITY_TYPE.equals(entityType) && jsonField.getKey().equals(JsonKey.of("thingId")) + )) + .and(Predicate.not(jsonField -> + POLICY_ENTITY_TYPE.equals(entityType) && jsonField.getKey().equals(JsonKey.of("policyId")) + )); } else { return FieldType.notHidden(); } } - private static Predicate calculatePredicateForNew(final JsonPointer resourcePath) { + private static Predicate calculatePredicateForNew(final JsonPointer resourcePath, + @Nullable final EntityType entityType + ) { if (resourcePath.isEmpty()) { - // filter "special fields" for e.g. on thing level the inline "_policy": - return jsonField -> !jsonField.getKeyName().startsWith("_"); + return calculatePredicate(resourcePath, entityType) + // filter "special fields" for e.g. on thing level the inline "_policy": + .and(jsonField -> !jsonField.getKeyName().startsWith("_")); } else { - return jsonField -> true; + return calculatePredicate(resourcePath, entityType); } }