Skip to content

Commit

Permalink
fix "If-Equal" header predicate for new different from predicate for …
Browse files Browse the repository at this point in the history
…existing

* causing that e.g. the existing Json did not contain "thingId" whereas the new one did
  • Loading branch information
thjaeckle committed Feb 10, 2025
1 parent 84a7061 commit 28e2930
Showing 1 changed file with 33 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -52,6 +54,9 @@ public final class IfEqualPreconditionHeader<C extends Command<?>> 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;
Expand Down Expand Up @@ -132,14 +137,18 @@ private Boolean meetsConditionForModifyCommand(final Entity<?> entity,

return withOptionalEntity.getEntity()
.map(newValue -> {
final Predicate<JsonField> fieldPredicate = calculatePredicate(command.getResourcePath());
final Predicate<JsonField> fieldPredicate = calculatePredicate(command.getResourcePath(),
entity.getEntityId().map(EntityId::getEntityType).orElse(null));
final Optional<JsonValue> 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;
}
Expand All @@ -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();
Expand Down Expand Up @@ -240,7 +252,8 @@ private C adjustMergeCommandByOnlyKeepingChanges(final C command,

return withOptionalEntity.getEntity()
.map(newValue -> {
final Predicate<JsonField> fieldPredicate = calculatePredicate(command.getResourcePath());
final Predicate<JsonField> 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) {
Expand All @@ -259,22 +272,31 @@ private C adjustMergeCommandByOnlyKeepingChanges(final C command,
.orElse(command);
}

private static Predicate<JsonField> calculatePredicate(final JsonPointer resourcePath) {
private static Predicate<JsonField> 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<JsonField> calculatePredicateForNew(final JsonPointer resourcePath) {
private static Predicate<JsonField> 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);
}
}

Expand Down

0 comments on commit 28e2930

Please sign in to comment.