Change the behavior of resource registration to fix ONOS-3827
Treat as a failure when ID is found but the value is not found
Change-Id: I032d25885897d662e49223a7b506eda8e5550a36
diff --git a/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java b/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java
index a6c3e57..934dfea 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java
@@ -19,6 +19,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
@@ -507,25 +508,29 @@
// computational complexity: O(n) where n is the number of the specified value
private boolean appendValues(TransactionalMap<DiscreteResourceId, Set<Resource>> map,
DiscreteResourceId key, List<Resource> values) {
- Set<Resource> oldValues = map.putIfAbsent(key, new LinkedHashSet<>(values));
+ Set<Resource> requested = new LinkedHashSet<>(values);
+ Set<Resource> oldValues = map.putIfAbsent(key, requested);
if (oldValues == null) {
return true;
}
- Set<ResourceId> oldIds = oldValues.stream()
- .map(Resource::id)
- .collect(Collectors.toSet());
- // values whose IDs don't match any IDs of oldValues
- Set<Resource> addedValues = values.stream()
- .filter(x -> !oldIds.contains(x.id()))
- .collect(Collectors.toCollection(LinkedHashSet::new));
- // no new ID, then no-op
+ Set<Resource> addedValues = Sets.difference(requested, oldValues);
+ // no new value, then no-op
if (addedValues.isEmpty()) {
// don't write to map because all values are already stored
return true;
}
- LinkedHashSet<Resource> newValues = new LinkedHashSet<>(oldValues);
+ Set<ResourceId> addedIds = addedValues.stream()
+ .map(Resource::id)
+ .collect(Collectors.toSet());
+ // if the value is not found but the same ID is found
+ // (this happens only when being continuous resource)
+ if (oldValues.stream().anyMatch(x -> addedIds.contains(x.id()))) {
+ // no-op, but indicating failure (reject the request)
+ return false;
+ }
+ Set<Resource> newValues = new LinkedHashSet<>(oldValues);
newValues.addAll(addedValues);
return map.replace(key, oldValues, newValues);
}