HIGUCHI Yuta
Committed by Yuta HIGUCHI

Bugfix: OpticalPortOperator should be able to overwrite port number.

- bug introduced in ONOS-3503.
- added exact equality comparison method to PortNumber
- removed null PortNumber case handling test

Change-Id: I6d1f191b5a64b79426de9d80cffadd6c9de96d56
(cherry picked from commit fdb82fa4)
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.net; 16 package org.onosproject.net;
17 17
18 +import com.google.common.base.Objects;
18 import com.google.common.base.Supplier; 19 import com.google.common.base.Supplier;
19 import com.google.common.base.Suppliers; 20 import com.google.common.base.Suppliers;
20 import com.google.common.collect.ImmutableMap; 21 import com.google.common.collect.ImmutableMap;
...@@ -273,4 +274,21 @@ public final class PortNumber { ...@@ -273,4 +274,21 @@ public final class PortNumber {
273 } 274 }
274 return false; 275 return false;
275 } 276 }
277 +
278 + /**
279 + * Indicates whether some other PortNumber object is equal to this one
280 + * including it's name.
281 + *
282 + * @param that other {@link PortNumber} instance to compare
283 + * @return true if equal, false otherwise
284 + */
285 + public boolean exactlyEquals(PortNumber that) {
286 + if (this == that) {
287 + return true;
288 + }
289 +
290 + return this.equals(that) &&
291 + this.hasName == that.hasName &&
292 + Objects.equal(this.name, that.name);
293 + }
276 } 294 }
......
...@@ -20,6 +20,7 @@ import org.onosproject.net.AbstractDescription; ...@@ -20,6 +20,7 @@ import org.onosproject.net.AbstractDescription;
20 import org.onosproject.net.PortNumber; 20 import org.onosproject.net.PortNumber;
21 import org.onosproject.net.SparseAnnotations; 21 import org.onosproject.net.SparseAnnotations;
22 22
23 +import static com.google.common.base.Preconditions.checkNotNull;
23 import static org.onosproject.net.Port.Type; 24 import static org.onosproject.net.Port.Type;
24 import com.google.common.base.Objects; 25 import com.google.common.base.Objects;
25 26
...@@ -61,7 +62,7 @@ public class DefaultPortDescription extends AbstractDescription ...@@ -61,7 +62,7 @@ public class DefaultPortDescription extends AbstractDescription
61 Type type, long portSpeed, 62 Type type, long portSpeed,
62 SparseAnnotations...annotations) { 63 SparseAnnotations...annotations) {
63 super(annotations); 64 super(annotations);
64 - this.number = number; 65 + this.number = checkNotNull(number);
65 this.isEnabled = isEnabled; 66 this.isEnabled = isEnabled;
66 this.type = type; 67 this.type = type;
67 this.portSpeed = portSpeed; 68 this.portSpeed = portSpeed;
......
...@@ -21,7 +21,7 @@ import org.junit.Test; ...@@ -21,7 +21,7 @@ import org.junit.Test;
21 import org.onosproject.net.PortNumber.Logical; 21 import org.onosproject.net.PortNumber.Logical;
22 22
23 import static java.util.stream.Collectors.toList; 23 import static java.util.stream.Collectors.toList;
24 -import static org.junit.Assert.assertEquals; 24 +import static org.junit.Assert.*;
25 import static org.onosproject.net.PortNumber.portNumber; 25 import static org.onosproject.net.PortNumber.portNumber;
26 26
27 import java.util.List; 27 import java.util.List;
...@@ -77,4 +77,16 @@ public class PortNumberTest { ...@@ -77,4 +77,16 @@ public class PortNumberTest {
77 ps.forEach(p -> assertEquals(p, PortNumber.fromString(p.toString()))); 77 ps.forEach(p -> assertEquals(p, PortNumber.fromString(p.toString())));
78 } 78 }
79 79
80 + @Test
81 + public void exactlyEquals() {
82 + assertTrue(portNumber(0).exactlyEquals(portNumber(0)));
83 + assertTrue(portNumber(0, "foo").exactlyEquals(portNumber(0, "foo")));
84 +
85 + assertFalse(portNumber(0, "foo").exactlyEquals(portNumber(0, "bar")));
86 + assertFalse(portNumber(0, "foo").exactlyEquals(portNumber(0)));
87 + assertFalse(portNumber(0, "foo").exactlyEquals(portNumber(1, "foo")));
88 +
89 + assertFalse(portNumber(123).exactlyEquals(portNumber(123, "123")));
90 + }
91 +
80 } 92 }
......
...@@ -102,50 +102,64 @@ public final class OpticalPortOperator implements ConfigOperator { ...@@ -102,50 +102,64 @@ public final class OpticalPortOperator implements ConfigOperator {
102 } 102 }
103 103
104 // updates a port description whose port type has not changed. 104 // updates a port description whose port type has not changed.
105 - private static PortDescription updateDescription( 105 + /**
106 - PortNumber port, SparseAnnotations sa, PortDescription descr) { 106 + * Updates {@link PortDescription} using specified number and annotations.
107 + *
108 + * @param port {@link PortNumber} to use in updated description
109 + * @param sa annotations to use in updated description
110 + * @param descr base {@link PortDescription}
111 + * @return updated {@link PortDescription}
112 + */
113 + private static PortDescription updateDescription(PortNumber port,
114 + SparseAnnotations sa,
115 + PortDescription descr) {
116 +
117 + // TODO This switch can go away once deprecation is complete.
107 switch (descr.type()) { 118 switch (descr.type()) {
108 case OMS: 119 case OMS:
109 if (descr instanceof OmsPortDescription) { 120 if (descr instanceof OmsPortDescription) {
110 - // TODO This block can go away once deprecation is complete.
111 OmsPortDescription oms = (OmsPortDescription) descr; 121 OmsPortDescription oms = (OmsPortDescription) descr;
112 return omsPortDescription(port, oms.isEnabled(), oms.minFrequency(), 122 return omsPortDescription(port, oms.isEnabled(), oms.minFrequency(),
113 oms.maxFrequency(), oms.grid(), sa); 123 oms.maxFrequency(), oms.grid(), sa);
114 } 124 }
115 - return descr; 125 + break;
116 case OCH: 126 case OCH:
117 // We might need to update lambda below with STATIC_LAMBDA. 127 // We might need to update lambda below with STATIC_LAMBDA.
118 if (descr instanceof OchPortDescription) { 128 if (descr instanceof OchPortDescription) {
119 - // TODO This block can go away once deprecation is complete.
120 OchPortDescription och = (OchPortDescription) descr; 129 OchPortDescription och = (OchPortDescription) descr;
121 return ochPortDescription(port, och.isEnabled(), och.signalType(), 130 return ochPortDescription(port, och.isEnabled(), och.signalType(),
122 och.isTunable(), och.lambda(), sa); 131 och.isTunable(), och.lambda(), sa);
123 } 132 }
124 - return descr; 133 + break;
125 case ODUCLT: 134 case ODUCLT:
126 if (descr instanceof OduCltPortDescription) { 135 if (descr instanceof OduCltPortDescription) {
127 - // TODO This block can go away once deprecation is complete.
128 OduCltPortDescription odu = (OduCltPortDescription) descr; 136 OduCltPortDescription odu = (OduCltPortDescription) descr;
129 return oduCltPortDescription(port, odu.isEnabled(), odu.signalType(), sa); 137 return oduCltPortDescription(port, odu.isEnabled(), odu.signalType(), sa);
130 } 138 }
131 - return descr; 139 + break;
132 case PACKET: 140 case PACKET:
133 case FIBER: 141 case FIBER:
134 case COPPER: 142 case COPPER:
135 - // TODO: it should be safe to just return descr. confirm and fix 143 + break;
136 - return new DefaultPortDescription(port, descr.isEnabled(), descr.type(),
137 - descr.portSpeed(), sa);
138 case OTU: 144 case OTU:
139 if (descr instanceof OtuPortDescription) { 145 if (descr instanceof OtuPortDescription) {
140 - // TODO This block can go away once deprecation is complete.
141 OtuPortDescription otu = (OtuPortDescription) descr; 146 OtuPortDescription otu = (OtuPortDescription) descr;
142 return otuPortDescription(port, otu.isEnabled(), otu.signalType(), sa); 147 return otuPortDescription(port, otu.isEnabled(), otu.signalType(), sa);
143 } 148 }
144 - return descr; 149 + break;
145 default: 150 default:
146 log.warn("Unsupported optical port type {} - can't update", descr.type()); 151 log.warn("Unsupported optical port type {} - can't update", descr.type());
147 return descr; 152 return descr;
148 } 153 }
154 + if (port.exactlyEquals(descr.portNumber()) && sa.equals(descr.annotations())) {
155 + // result is no-op
156 + return descr;
157 + }
158 + return new DefaultPortDescription(port,
159 + descr.isEnabled(),
160 + descr.type(),
161 + descr.portSpeed(),
162 + sa);
149 } 163 }
150 164
151 /** 165 /**
......
...@@ -28,62 +28,94 @@ import org.onosproject.net.DeviceId; ...@@ -28,62 +28,94 @@ import org.onosproject.net.DeviceId;
28 import org.onosproject.net.Port; 28 import org.onosproject.net.Port;
29 import org.onosproject.net.PortNumber; 29 import org.onosproject.net.PortNumber;
30 import org.onosproject.net.SparseAnnotations; 30 import org.onosproject.net.SparseAnnotations;
31 -import org.onosproject.net.device.OduCltPortDescription; 31 +import org.onosproject.net.device.PortDescription;
32 -
33 import com.fasterxml.jackson.databind.ObjectMapper; 32 import com.fasterxml.jackson.databind.ObjectMapper;
34 import com.fasterxml.jackson.databind.node.JsonNodeFactory; 33 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
35 34
36 import static org.junit.Assert.assertEquals; 35 import static org.junit.Assert.assertEquals;
36 +import static org.onosproject.net.optical.device.OduCltPortHelper.oduCltPortDescription;
37 37
38 public class OpticalPortOperatorTest { 38 public class OpticalPortOperatorTest {
39 private static final DeviceId DID = DeviceId.deviceId("op-test"); 39 private static final DeviceId DID = DeviceId.deviceId("op-test");
40 - private static final String TPNAME = "test-port-100"; 40 + private static final long PORT_NUMBER = 100;
41 - private static final String SPNAME = "out-port-200"; 41 + private static final String CFG_KEY = "optical";
42 - private static final String CFGNAME = "cfg-name"; 42 +
43 + private static final String CFG_PORT_NAME = "cfg-name";
44 + private static final long CFG_STATIC_LAMBDA = 300L;
43 45
44 - private static final PortNumber NAMED = PortNumber.portNumber(100, TPNAME); 46 + private static final String DESC_PORT_NAME = "test-port-100";
45 - private static final PortNumber UNNAMED = PortNumber.portNumber(101); 47 + private static final PortNumber NAMED = PortNumber.portNumber(PORT_NUMBER, DESC_PORT_NAME);
46 - private static final ConnectPoint NCP = new ConnectPoint(DID, UNNAMED); 48 + private static final PortNumber UNNAMED = PortNumber.portNumber(PORT_NUMBER);
47 49
50 + private static final String DESC_STATIC_PORT = "out-port-200";
48 private static final SparseAnnotations SA = DefaultAnnotations.builder() 51 private static final SparseAnnotations SA = DefaultAnnotations.builder()
49 - .set(AnnotationKeys.STATIC_PORT, SPNAME) 52 + .set(AnnotationKeys.STATIC_PORT, DESC_STATIC_PORT)
50 .build(); 53 .build();
51 54
52 - private static final OduCltPortDescription N_DESC = new OduCltPortDescription( 55 + private static final PortDescription N_DESC = oduCltPortDescription(
53 NAMED, true, CltSignalType.CLT_100GBE, SA); 56 NAMED, true, CltSignalType.CLT_100GBE, SA);
54 - private static final OduCltPortDescription FAULTY = new OduCltPortDescription( 57 + private static final PortDescription U_DESC = oduCltPortDescription(
55 - null, true, CltSignalType.CLT_100GBE); 58 + UNNAMED, true, CltSignalType.CLT_100GBE, SA);
56 59
57 private final ConfigApplyDelegate delegate = new MockCfgDelegate(); 60 private final ConfigApplyDelegate delegate = new MockCfgDelegate();
58 private final ObjectMapper mapper = new ObjectMapper(); 61 private final ObjectMapper mapper = new ObjectMapper();
59 62
60 - private static final OpticalPortConfig N_OPC = new OpticalPortConfig(); 63 + private static final ConnectPoint CP = new ConnectPoint(DID, UNNAMED);
61 - private static final OpticalPortConfig UNN_OPC = new OpticalPortConfig(); 64 +
65 + private static final OpticalPortConfig OPC = new OpticalPortConfig();
62 66
63 @Before 67 @Before
64 public void setUp() { 68 public void setUp() {
65 - N_OPC.init(NCP, TPNAME, JsonNodeFactory.instance.objectNode(), mapper, delegate); 69 + OPC.init(CP, CFG_KEY, JsonNodeFactory.instance.objectNode(), mapper, delegate);
66 - UNN_OPC.init(NCP, TPNAME, JsonNodeFactory.instance.objectNode(), mapper, delegate);
67 -
68 - N_OPC.portName(CFGNAME).portNumberName(101L).portType(Port.Type.ODUCLT).staticLambda(300L);
69 - UNN_OPC.portType(Port.Type.ODUCLT);
70 } 70 }
71 71
72 - @Test(expected = RuntimeException.class) 72 + @Test
73 - public void testDescOps() { 73 + public void testConfigPortName() {
74 - // port-null desc + opc with port number name 74 + OPC.portType(Port.Type.ODUCLT)
75 - OduCltPortDescription res = (OduCltPortDescription) OpticalPortOperator.combine(N_OPC, FAULTY); 75 + .portNumberName(PORT_NUMBER)
76 - assertEquals(CFGNAME, res.portNumber().name()); 76 + .portName(CFG_PORT_NAME);
77 +
78 + PortDescription res;
77 // full desc + opc with name 79 // full desc + opc with name
78 - assertEquals(TPNAME, N_DESC.portNumber().name()); 80 + res = OpticalPortOperator.combine(OPC, N_DESC);
79 - res = (OduCltPortDescription) OpticalPortOperator.combine(N_OPC, N_DESC); 81 + assertEquals("Configured port name expected",
82 + CFG_PORT_NAME, res.portNumber().name());
83 + assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT));
84 +
85 + res = OpticalPortOperator.combine(OPC, U_DESC);
86 + assertEquals("Configured port name expected",
87 + CFG_PORT_NAME, res.portNumber().name());
88 + assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT));
89 + }
90 +
91 + @Test
92 + public void testConfigAddStaticLambda() {
93 + OPC.portType(Port.Type.ODUCLT)
94 + .portNumberName(PORT_NUMBER)
95 + .staticLambda(CFG_STATIC_LAMBDA);
96 +
97 + PortDescription res;
98 + res = OpticalPortOperator.combine(OPC, N_DESC);
99 + assertEquals("Original port name expected",
100 + DESC_PORT_NAME, res.portNumber().name());
101 + assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT));
80 long sl = Long.valueOf(res.annotations().value(AnnotationKeys.STATIC_LAMBDA)); 102 long sl = Long.valueOf(res.annotations().value(AnnotationKeys.STATIC_LAMBDA));
81 - assertEquals(CFGNAME, res.portNumber().name()); 103 + assertEquals(CFG_STATIC_LAMBDA, sl);
82 - assertEquals(300L, sl); 104 + }
83 - // port-null desc + opc without port number name - throws RE 105 +
84 - res = (OduCltPortDescription) OpticalPortOperator.combine(UNN_OPC, FAULTY); 106 + @Test
107 + public void testEmptyConfig() {
108 + OPC.portType(Port.Type.ODUCLT)
109 + .portNumberName(PORT_NUMBER);
110 +
111 + PortDescription res;
112 + res = OpticalPortOperator.combine(OPC, N_DESC);
113 + assertEquals("Configured port name expected",
114 + DESC_PORT_NAME, res.portNumber().name());
115 + assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT));
85 } 116 }
86 117
118 +
87 private class MockCfgDelegate implements ConfigApplyDelegate { 119 private class MockCfgDelegate implements ConfigApplyDelegate {
88 120
89 @Override 121 @Override
......