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 { ...@@ -98,14 +98,25 @@ final class EncodableDiscreteResources implements DiscreteResources {
98 public DiscreteResources difference(DiscreteResources other) { 98 public DiscreteResources difference(DiscreteResources other) {
99 if (other instanceof EncodableDiscreteResources) { 99 if (other instanceof EncodableDiscreteResources) {
100 EncodableDiscreteResources cast = (EncodableDiscreteResources) other; 100 EncodableDiscreteResources cast = (EncodableDiscreteResources) other;
101 - Map<Class<?>, EncodedDiscreteResources> newMap = 101 +
102 - Stream.concat(this.map.entrySet().stream(), cast.map.entrySet().stream()) 102 + Map<Class<?>, EncodedDiscreteResources> newMap = new LinkedHashMap<>();
103 - .filter(entry -> this.map.containsKey(entry.getKey())) 103 + for (Class<?> key : this.map.keySet()) {
104 - .collect(Collectors.toMap( 104 + EncodedDiscreteResources thisValues = this.map.get(key);
105 - Map.Entry::getKey, 105 + if (!cast.map.containsKey(key)) {
106 - Map.Entry::getValue, 106 + newMap.put(key, thisValues);
107 - EncodedDiscreteResources::difference, 107 + continue;
108 - LinkedHashMap::new)); 108 + }
109 + EncodedDiscreteResources otherValues = cast.map.get(key);
110 + EncodedDiscreteResources diff = thisValues.difference(otherValues);
111 + // omit empty resources from a new resource set
112 + // empty EncodedDiscreteResources can't deserialize due to
113 + // inability to reproduce a Class<?> instance from the serialized data
114 + if (diff.isEmpty()) {
115 + continue;
116 + }
117 + newMap.put(key, diff);
118 + }
119 +
109 return of(parent, newMap); 120 return of(parent, newMap);
110 } else if (other instanceof EmptyDiscreteResources) { 121 } else if (other instanceof EmptyDiscreteResources) {
111 return this; 122 return this;
......
...@@ -18,16 +18,19 @@ package org.onosproject.store.resource.impl; ...@@ -18,16 +18,19 @@ package org.onosproject.store.resource.impl;
18 18
19 import com.google.common.collect.ImmutableSet; 19 import com.google.common.collect.ImmutableSet;
20 import org.junit.Test; 20 import org.junit.Test;
21 +import org.onlab.packet.VlanId;
21 import org.onosproject.net.DeviceId; 22 import org.onosproject.net.DeviceId;
22 import org.onosproject.net.PortNumber; 23 import org.onosproject.net.PortNumber;
23 import org.onosproject.net.resource.DiscreteResource; 24 import org.onosproject.net.resource.DiscreteResource;
24 import org.onosproject.net.resource.Resources; 25 import org.onosproject.net.resource.Resources;
25 import org.onosproject.store.service.Serializer; 26 import org.onosproject.store.service.Serializer;
26 27
28 +import java.util.List;
27 import java.util.Optional; 29 import java.util.Optional;
28 import java.util.Set; 30 import java.util.Set;
29 import java.util.stream.Collectors; 31 import java.util.stream.Collectors;
30 import java.util.stream.IntStream; 32 import java.util.stream.IntStream;
33 +import java.util.stream.Stream;
31 34
32 import static org.hamcrest.Matchers.is; 35 import static org.hamcrest.Matchers.is;
33 import static org.junit.Assert.assertThat; 36 import static org.junit.Assert.assertThat;
...@@ -83,6 +86,30 @@ public class EncodableDiscreteResourcesTest { ...@@ -83,6 +86,30 @@ public class EncodableDiscreteResourcesTest {
83 } 86 }
84 87
85 @Test 88 @Test
89 + public void testSerializeInstanceContainingEmptyEncodedDiscreteResources() {
90 + DiscreteResource device = Resources.discrete(DeviceId.deviceId("a")).resource();
91 + List<PortNumber> ports = IntStream.range(0, 1)
92 + .mapToObj(PortNumber::portNumber)
93 + .collect(Collectors.toList());
94 + List<VlanId> vlans = IntStream.range(0, 2)
95 + .mapToObj(x -> VlanId.vlanId((short) x))
96 + .collect(Collectors.toList());
97 +
98 + Set<DiscreteResource> originalResources = Stream.concat(ports.stream(), vlans.stream())
99 + .map(device::child)
100 + .collect(Collectors.toSet());
101 + DiscreteResources sut = EncodableDiscreteResources.of(originalResources);
102 +
103 + Set<DiscreteResource> portOnlyResources = ports.stream().map(device::child).collect(Collectors.toSet());
104 + DiscreteResources other = EncodableDiscreteResources.of(portOnlyResources);
105 +
106 + DiscreteResources diff = sut.difference(other);
107 +
108 + byte[] bytes = serializer.encode(diff);
109 + assertThat(serializer.decode(bytes), is(diff));
110 + }
111 +
112 + @Test
86 public void testIfDifferenceIsNotEmpty() { 113 public void testIfDifferenceIsNotEmpty() {
87 DiscreteResource res1 = Resources.discrete(DeviceId.deviceId("a"), PortNumber.portNumber(1)).resource(); 114 DiscreteResource res1 = Resources.discrete(DeviceId.deviceId("a"), PortNumber.portNumber(1)).resource();
88 DiscreteResource res2 = Resources.discrete(DeviceId.deviceId("a"), PortNumber.portNumber(2)).resource(); 115 DiscreteResource res2 = Resources.discrete(DeviceId.deviceId("a"), PortNumber.portNumber(2)).resource();
......