Sho SHIMIZU
Committed by Gerrit Code Review

Fix NoSuchElementException reported in ONOS-4763 and ONOS-4757

Change-Id: I973b6c33f02defac3463b6e53ea177056f1f9714
......@@ -98,14 +98,25 @@ final class EncodableDiscreteResources implements DiscreteResources {
public DiscreteResources difference(DiscreteResources other) {
if (other instanceof EncodableDiscreteResources) {
EncodableDiscreteResources cast = (EncodableDiscreteResources) other;
Map<Class<?>, EncodedDiscreteResources> newMap =
Stream.concat(this.map.entrySet().stream(), cast.map.entrySet().stream())
.filter(entry -> this.map.containsKey(entry.getKey()))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
EncodedDiscreteResources::difference,
LinkedHashMap::new));
Map<Class<?>, EncodedDiscreteResources> newMap = new LinkedHashMap<>();
for (Class<?> key : this.map.keySet()) {
EncodedDiscreteResources thisValues = this.map.get(key);
if (!cast.map.containsKey(key)) {
newMap.put(key, thisValues);
continue;
}
EncodedDiscreteResources otherValues = cast.map.get(key);
EncodedDiscreteResources diff = thisValues.difference(otherValues);
// omit empty resources from a new resource set
// empty EncodedDiscreteResources can't deserialize due to
// inability to reproduce a Class<?> instance from the serialized data
if (diff.isEmpty()) {
continue;
}
newMap.put(key, diff);
}
return of(parent, newMap);
} else if (other instanceof EmptyDiscreteResources) {
return this;
......
......@@ -18,16 +18,19 @@ package org.onosproject.store.resource.impl;
import com.google.common.collect.ImmutableSet;
import org.junit.Test;
import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.resource.DiscreteResource;
import org.onosproject.net.resource.Resources;
import org.onosproject.store.service.Serializer;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
......@@ -83,6 +86,30 @@ public class EncodableDiscreteResourcesTest {
}
@Test
public void testSerializeInstanceContainingEmptyEncodedDiscreteResources() {
DiscreteResource device = Resources.discrete(DeviceId.deviceId("a")).resource();
List<PortNumber> ports = IntStream.range(0, 1)
.mapToObj(PortNumber::portNumber)
.collect(Collectors.toList());
List<VlanId> vlans = IntStream.range(0, 2)
.mapToObj(x -> VlanId.vlanId((short) x))
.collect(Collectors.toList());
Set<DiscreteResource> originalResources = Stream.concat(ports.stream(), vlans.stream())
.map(device::child)
.collect(Collectors.toSet());
DiscreteResources sut = EncodableDiscreteResources.of(originalResources);
Set<DiscreteResource> portOnlyResources = ports.stream().map(device::child).collect(Collectors.toSet());
DiscreteResources other = EncodableDiscreteResources.of(portOnlyResources);
DiscreteResources diff = sut.difference(other);
byte[] bytes = serializer.encode(diff);
assertThat(serializer.decode(bytes), is(diff));
}
@Test
public void testIfDifferenceIsNotEmpty() {
DiscreteResource res1 = Resources.discrete(DeviceId.deviceId("a"), PortNumber.portNumber(1)).resource();
DiscreteResource res2 = Resources.discrete(DeviceId.deviceId("a"), PortNumber.portNumber(2)).resource();
......