Yuta HIGUCHI
Committed by Gerrit Code Review

[ONOS-4691] Refactoring OpticalPortOperator (2/3)

- Define ConfigOperator for a Port
- Refactor OpticalPortOperator as PortConfigOperator
- Add plug-in mechanism for PortConfigOperator on DeviceManager
- Move OpticalPortConfig, OpticalPortOperator to optical-model bundle

Change-Id: I5d416305b0c1b0e31e0ad64baa92d126303548bc
...@@ -4,7 +4,7 @@ COMPILE_DEPS = [ ...@@ -4,7 +4,7 @@ COMPILE_DEPS = [
4 ] 4 ]
5 5
6 TEST_DEPS = [ 6 TEST_DEPS = [
7 - '//lib:TEST', 7 + '//lib:TEST_ADAPTERS',
8 ] 8 ]
9 9
10 10
......
...@@ -47,6 +47,13 @@ ...@@ -47,6 +47,13 @@
47 47
48 <dependency> 48 <dependency>
49 <groupId>org.onosproject</groupId> 49 <groupId>org.onosproject</groupId>
50 + <artifactId>onos-api</artifactId>
51 + <classifier>tests</classifier>
52 + <scope>test</scope>
53 + </dependency>
54 +
55 + <dependency>
56 + <groupId>org.onosproject</groupId>
50 <artifactId>onlab-junit</artifactId> 57 <artifactId>onlab-junit</artifactId>
51 <scope>test</scope> 58 <scope>test</scope>
52 </dependency> 59 </dependency>
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.onosproject.net.config.basics; 16 +package org.onosproject.net.optical.config;
17 17
18 import java.util.Optional; 18 import java.util.Optional;
19 19
...@@ -30,6 +30,7 @@ import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL; ...@@ -30,6 +30,7 @@ import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL;
30 * Configurations for an optical port on a device. 30 * Configurations for an optical port on a device.
31 */ 31 */
32 public final class OpticalPortConfig extends Config<ConnectPoint> { 32 public final class OpticalPortConfig extends Config<ConnectPoint> {
33 +
33 // optical type {OMS, OCH, ODUClt, fiber} 34 // optical type {OMS, OCH, ODUClt, fiber}
34 public static final String TYPE = "type"; 35 public static final String TYPE = "type";
35 36
......
...@@ -13,17 +13,26 @@ ...@@ -13,17 +13,26 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.onosproject.net.device.impl; 16 +package org.onosproject.net.optical.config;
17 17
18 import static org.onosproject.net.optical.device.OchPortHelper.ochPortDescription; 18 import static org.onosproject.net.optical.device.OchPortHelper.ochPortDescription;
19 import static org.onosproject.net.optical.device.OduCltPortHelper.oduCltPortDescription; 19 import static org.onosproject.net.optical.device.OduCltPortHelper.oduCltPortDescription;
20 import static org.onosproject.net.optical.device.OmsPortHelper.omsPortDescription; 20 import static org.onosproject.net.optical.device.OmsPortHelper.omsPortDescription;
21 import static org.onosproject.net.optical.device.OtuPortHelper.otuPortDescription; 21 import static org.onosproject.net.optical.device.OtuPortHelper.otuPortDescription;
22 import static org.slf4j.LoggerFactory.getLogger; 22 import static org.slf4j.LoggerFactory.getLogger;
23 -import org.onosproject.net.config.ConfigOperator; 23 +
24 -import org.onosproject.net.config.basics.OpticalPortConfig; 24 +import java.util.Set;
25 +
26 +import static com.google.common.base.MoreObjects.firstNonNull;
27 +import static com.google.common.base.Preconditions.checkNotNull;
28 +
29 +import org.onosproject.net.config.NetworkConfigService;
30 +import org.onosproject.net.config.PortConfigOperator;
25 import org.onosproject.net.AnnotationKeys; 31 import org.onosproject.net.AnnotationKeys;
32 +import org.onosproject.net.ConnectPoint;
26 import org.onosproject.net.DefaultAnnotations; 33 import org.onosproject.net.DefaultAnnotations;
34 +import org.onosproject.net.Port;
35 +import org.onosproject.net.Port.Type;
27 import org.onosproject.net.PortNumber; 36 import org.onosproject.net.PortNumber;
28 import org.onosproject.net.SparseAnnotations; 37 import org.onosproject.net.SparseAnnotations;
29 import org.onosproject.net.device.DefaultPortDescription; 38 import org.onosproject.net.device.DefaultPortDescription;
...@@ -34,63 +43,85 @@ import org.onosproject.net.device.OtuPortDescription; ...@@ -34,63 +43,85 @@ import org.onosproject.net.device.OtuPortDescription;
34 import org.onosproject.net.device.PortDescription; 43 import org.onosproject.net.device.PortDescription;
35 import org.slf4j.Logger; 44 import org.slf4j.Logger;
36 45
46 +import com.google.common.collect.Sets;
47 +
37 /** 48 /**
38 * Implementations of merge policies for various sources of optical port 49 * Implementations of merge policies for various sources of optical port
39 * configuration information. This includes applications, provides, and network 50 * configuration information. This includes applications, provides, and network
40 * configurations. 51 * configurations.
41 */ 52 */
42 -public final class OpticalPortOperator implements ConfigOperator { 53 +public final class OpticalPortOperator implements PortConfigOperator {
43 54
44 private static final Logger log = getLogger(OpticalPortOperator.class); 55 private static final Logger log = getLogger(OpticalPortOperator.class);
45 56
46 - private OpticalPortOperator() { 57 + /**
58 + * Port.Type this PortConfigOperator reacts on.
59 + */
60 + private final Set<Port.Type> optical = Sets.immutableEnumSet(Port.Type.ODUCLT,
61 + Port.Type.OMS,
62 + Port.Type.OCH,
63 + Port.Type.OTU,
64 + Port.Type.FIBER,
65 + Port.Type.PACKET);
66 +
67 + private NetworkConfigService networkConfigService;
68 +
69 +
70 + public OpticalPortOperator() {
71 + }
72 +
73 + @Override
74 + public void bindService(NetworkConfigService networkConfigService) {
75 + this.networkConfigService = networkConfigService;
76 + }
77 +
78 + private OpticalPortConfig lookupConfig(ConnectPoint cp) {
79 + if (networkConfigService == null) {
80 + return null;
81 + }
82 + return networkConfigService.getConfig(cp, OpticalPortConfig.class);
47 } 83 }
48 84
49 /** 85 /**
50 * Generates a PortDescription containing fields from a PortDescription and 86 * Generates a PortDescription containing fields from a PortDescription and
51 * an OpticalPortConfig. 87 * an OpticalPortConfig.
52 * 88 *
53 - * @param opc the port config entity from network config 89 + * @param cp {@link ConnectPoint} representing the port.
54 - * @param descr a PortDescription 90 + * @param descr input {@link PortDescription}
55 - * @return PortDescription based on both sources 91 + * @return Combined {@link PortDescription}
56 */ 92 */
57 - public static PortDescription combine(OpticalPortConfig opc, PortDescription descr) { 93 + @Override
94 + public PortDescription combine(ConnectPoint cp, PortDescription descr) {
95 + checkNotNull(cp);
96 +
97 + // short-circuit for non-optical ports
98 + // must be removed if we need type override
99 + if (descr != null && !optical.contains(descr.type())) {
100 + return descr;
101 + }
102 +
103 + OpticalPortConfig opc = lookupConfig(cp);
58 if (opc == null) { 104 if (opc == null) {
59 return descr; 105 return descr;
60 } 106 }
61 107
62 - PortNumber port = descr.portNumber(); 108 + PortNumber number = descr.portNumber();
63 - final String name = opc.name(); 109 + // handle PortNumber "name" portion
64 - final String numName = opc.numberName(); 110 + if (!opc.name().isEmpty()) {
65 - // if the description is null, or the current description port name != config name, 111 + number = PortNumber.portNumber(descr.portNumber().toLong(), opc.name());
66 - // create a new PortNumber.
67 - PortNumber newPort = null;
68 - if (port == null) {
69 - // try to get the portNumber from the numName.
70 - if (!numName.isEmpty()) {
71 - final long pn = Long.parseLong(numName);
72 - newPort = (!name.isEmpty()) ? PortNumber.portNumber(pn, name) : PortNumber.portNumber(pn);
73 - } else {
74 - // we don't have defining info (a port number value)
75 - throw new RuntimeException("Possible misconfig, bailing on handling for: \n\t" + descr);
76 - }
77 - } else if ((!name.isEmpty()) && !name.equals(port.name())) {
78 - final long pn = (numName.isEmpty()) ? port.toLong() : Long.parseLong(numName);
79 - newPort = PortNumber.portNumber(pn, name);
80 } 112 }
81 113
82 - // Port type won't change unless we're overwriting a port completely. 114 + // handle additional annotations
83 - // Watch out for overwrites to avoid class cast craziness. 115 + SparseAnnotations annotations = combine(opc, descr.annotations());
84 - boolean noOwrite = opc.type() == descr.type();
85 116
86 - SparseAnnotations sa = combine(opc, descr.annotations()); 117 + // (Future work) handle type overwrite?
87 - if (noOwrite) { 118 + Type type = firstNonNull(opc.type(), descr.type());
88 - return updateDescription((newPort == null) ? port : newPort, sa, descr); 119 + if (type != descr.type()) {
89 - } else { 120 + // TODO: Do we need to be able to overwrite Port.Type?
90 - // TODO: must reconstruct a different type of PortDescription. 121 + log.warn("Port type overwrite requested for {}. Ignoring.", cp);
91 - log.info("Type rewrite from {} to {} required", descr.type(), opc.type());
92 } 122 }
93 - return descr; 123 +
124 + return updateDescription(number, annotations, descr);
94 } 125 }
95 126
96 // updates a port description whose port type has not changed. 127 // updates a port description whose port type has not changed.
...@@ -161,8 +192,9 @@ public final class OpticalPortOperator implements ConfigOperator { ...@@ -161,8 +192,9 @@ public final class OpticalPortOperator implements ConfigOperator {
161 * @param an the annotation 192 * @param an the annotation
162 * @return annotation combining both sources 193 * @return annotation combining both sources
163 */ 194 */
164 - public static SparseAnnotations combine(OpticalPortConfig opc, SparseAnnotations an) { 195 + private static SparseAnnotations combine(OpticalPortConfig opc, SparseAnnotations an) {
165 DefaultAnnotations.Builder b = DefaultAnnotations.builder(); 196 DefaultAnnotations.Builder b = DefaultAnnotations.builder();
197 + b.putAll(an);
166 if (!opc.staticPort().isEmpty()) { 198 if (!opc.staticPort().isEmpty()) {
167 b.set(AnnotationKeys.STATIC_PORT, opc.staticPort()); 199 b.set(AnnotationKeys.STATIC_PORT, opc.staticPort());
168 } 200 }
...@@ -173,7 +205,8 @@ public final class OpticalPortOperator implements ConfigOperator { ...@@ -173,7 +205,8 @@ public final class OpticalPortOperator implements ConfigOperator {
173 if (!opc.name().isEmpty()) { 205 if (!opc.name().isEmpty()) {
174 b.set(AnnotationKeys.PORT_NAME, opc.name()); 206 b.set(AnnotationKeys.PORT_NAME, opc.name());
175 } 207 }
176 - return DefaultAnnotations.union(an, b.build()); 208 + return b.build();
177 } 209 }
178 210
211 +
179 } 212 }
......
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 + * use this file except in compliance with the License. You may obtain a copy of
6 + * the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 + * License for the specific language governing permissions and limitations under
14 + * the License.
15 + */
16 +/**
17 + * Various optical model related configurations.
18 + */
19 +package org.onosproject.net.optical.config;
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.net.optical.internal;
17 +
18 +import static org.onosproject.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY;
19 +
20 +import org.apache.felix.scr.annotations.Activate;
21 +import org.apache.felix.scr.annotations.Component;
22 +import org.apache.felix.scr.annotations.Deactivate;
23 +import org.apache.felix.scr.annotations.Reference;
24 +import org.apache.felix.scr.annotations.ReferenceCardinality;
25 +import org.onosproject.net.ConnectPoint;
26 +import org.onosproject.net.config.ConfigFactory;
27 +import org.onosproject.net.config.NetworkConfigRegistry;
28 +import org.onosproject.net.config.PortConfigOperatorRegistry;
29 +import org.onosproject.net.optical.config.OpticalPortConfig;
30 +import org.onosproject.net.optical.config.OpticalPortOperator;
31 +import org.slf4j.Logger;
32 +import org.slf4j.LoggerFactory;
33 +
34 +/**
35 + * Loader which registers optical model related config, etc.
36 + */
37 +@Component(immediate = true)
38 +public class OpticalModelLoader {
39 +
40 + private final Logger log = LoggerFactory.getLogger(getClass());
41 +
42 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
43 + protected PortConfigOperatorRegistry portOperatorRegistry;
44 +
45 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
46 + protected NetworkConfigRegistry netcfgRegistry;
47 +
48 +
49 + private OpticalPortOperator opticalPortOp;
50 +
51 + private ConfigFactory<ConnectPoint, OpticalPortConfig>
52 + opticalPortConfigFactory = new ConfigFactory<ConnectPoint, OpticalPortConfig>(CONNECT_POINT_SUBJECT_FACTORY,
53 + OpticalPortConfig.class,
54 + "optical") {
55 + @Override
56 + public OpticalPortConfig createConfig() {
57 + return new OpticalPortConfig();
58 + }
59 + };
60 +
61 + @Activate
62 + protected void activate() {
63 + netcfgRegistry.registerConfigFactory(opticalPortConfigFactory);
64 +
65 + opticalPortOp = new OpticalPortOperator();
66 + portOperatorRegistry.registerPortConfigOperator(opticalPortOp,
67 + OpticalPortConfig.class);
68 +
69 + log.info("Started");
70 + }
71 +
72 + @Deactivate
73 + protected void deactivate() {
74 + portOperatorRegistry.unregisterPortConfigOperator(opticalPortOp);
75 +
76 + netcfgRegistry.unregisterConfigFactory(opticalPortConfigFactory);
77 + log.info("Stopped");
78 + }
79 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 + * use this file except in compliance with the License. You may obtain a copy of
6 + * the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 + * License for the specific language governing permissions and limitations under
14 + * the License.
15 + */
16 +/**
17 + * Internal tools for optical model.
18 + */
19 +package org.onosproject.net.optical.internal;
...@@ -13,15 +13,15 @@ ...@@ -13,15 +13,15 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.onosproject.incubator.net.config.basics; 16 +package org.onosproject.net.optical.config;
17 17
18 import static org.junit.Assert.assertEquals; 18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertFalse; 19 import static org.junit.Assert.assertFalse;
20 -import static org.onosproject.net.config.basics.OpticalPortConfig.TYPE; 20 +import static org.onosproject.net.optical.config.OpticalPortConfig.NAME;
21 -import static org.onosproject.net.config.basics.OpticalPortConfig.NAME; 21 +import static org.onosproject.net.optical.config.OpticalPortConfig.PORT;
22 -import static org.onosproject.net.config.basics.OpticalPortConfig.PORT; 22 +import static org.onosproject.net.optical.config.OpticalPortConfig.STATIC_LAMBDA;
23 -import static org.onosproject.net.config.basics.OpticalPortConfig.STATIC_LAMBDA; 23 +import static org.onosproject.net.optical.config.OpticalPortConfig.STATIC_PORT;
24 -import static org.onosproject.net.config.basics.OpticalPortConfig.STATIC_PORT; 24 +import static org.onosproject.net.optical.config.OpticalPortConfig.TYPE;
25 25
26 import java.io.IOException; 26 import java.io.IOException;
27 import java.util.Iterator; 27 import java.util.Iterator;
...@@ -41,7 +41,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; ...@@ -41,7 +41,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
41 import com.fasterxml.jackson.databind.node.JsonNodeFactory; 41 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
42 import com.fasterxml.jackson.databind.node.ObjectNode; 42 import com.fasterxml.jackson.databind.node.ObjectNode;
43 import com.google.common.collect.Lists; 43 import com.google.common.collect.Lists;
44 -import org.onosproject.net.config.basics.OpticalPortConfig;
45 44
46 public class OpticalPortConfigTest { 45 public class OpticalPortConfigTest {
47 private static final String FIELD = "ports"; 46 private static final String FIELD = "ports";
......
...@@ -13,14 +13,14 @@ ...@@ -13,14 +13,14 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.onosproject.net.device.impl; 16 +package org.onosproject.net.optical.config;
17 17
18 import org.junit.Before; 18 import org.junit.Before;
19 import org.junit.Test; 19 import org.junit.Test;
20 import org.onosproject.net.CltSignalType; 20 import org.onosproject.net.CltSignalType;
21 import org.onosproject.net.config.Config; 21 import org.onosproject.net.config.Config;
22 import org.onosproject.net.config.ConfigApplyDelegate; 22 import org.onosproject.net.config.ConfigApplyDelegate;
23 -import org.onosproject.net.config.basics.OpticalPortConfig; 23 +import org.onosproject.net.config.NetworkConfigServiceAdapter;
24 import org.onosproject.net.AnnotationKeys; 24 import org.onosproject.net.AnnotationKeys;
25 import org.onosproject.net.ConnectPoint; 25 import org.onosproject.net.ConnectPoint;
26 import org.onosproject.net.DefaultAnnotations; 26 import org.onosproject.net.DefaultAnnotations;
...@@ -29,6 +29,7 @@ import org.onosproject.net.Port; ...@@ -29,6 +29,7 @@ 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.PortDescription; 31 import org.onosproject.net.device.PortDescription;
32 +
32 import com.fasterxml.jackson.databind.ObjectMapper; 33 import com.fasterxml.jackson.databind.ObjectMapper;
33 import com.fasterxml.jackson.databind.node.JsonNodeFactory; 34 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
34 35
...@@ -62,27 +63,33 @@ public class OpticalPortOperatorTest { ...@@ -62,27 +63,33 @@ public class OpticalPortOperatorTest {
62 63
63 private static final ConnectPoint CP = new ConnectPoint(DID, UNNAMED); 64 private static final ConnectPoint CP = new ConnectPoint(DID, UNNAMED);
64 65
65 - private static final OpticalPortConfig OPC = new OpticalPortConfig(); 66 + private OpticalPortConfig opc;
67 +
68 + private OpticalPortOperator oper;
66 69
67 @Before 70 @Before
68 public void setUp() { 71 public void setUp() {
69 - OPC.init(CP, CFG_KEY, JsonNodeFactory.instance.objectNode(), mapper, delegate); 72 + opc = new OpticalPortConfig();
73 + opc.init(CP, CFG_KEY, JsonNodeFactory.instance.objectNode(), mapper, delegate);
74 +
75 + oper = new OpticalPortOperator();
76 + oper.bindService(new MockNetworkConfigService());
70 } 77 }
71 78
72 @Test 79 @Test
73 public void testConfigPortName() { 80 public void testConfigPortName() {
74 - OPC.portType(Port.Type.ODUCLT) 81 + opc.portType(Port.Type.ODUCLT)
75 .portNumberName(PORT_NUMBER) 82 .portNumberName(PORT_NUMBER)
76 .portName(CFG_PORT_NAME); 83 .portName(CFG_PORT_NAME);
77 84
78 PortDescription res; 85 PortDescription res;
79 // full desc + opc with name 86 // full desc + opc with name
80 - res = OpticalPortOperator.combine(OPC, N_DESC); 87 + res = oper.combine(CP, N_DESC);
81 assertEquals("Configured port name expected", 88 assertEquals("Configured port name expected",
82 CFG_PORT_NAME, res.portNumber().name()); 89 CFG_PORT_NAME, res.portNumber().name());
83 assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT)); 90 assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT));
84 91
85 - res = OpticalPortOperator.combine(OPC, U_DESC); 92 + res = oper.combine(CP, U_DESC);
86 assertEquals("Configured port name expected", 93 assertEquals("Configured port name expected",
87 CFG_PORT_NAME, res.portNumber().name()); 94 CFG_PORT_NAME, res.portNumber().name());
88 assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT)); 95 assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT));
...@@ -90,12 +97,12 @@ public class OpticalPortOperatorTest { ...@@ -90,12 +97,12 @@ public class OpticalPortOperatorTest {
90 97
91 @Test 98 @Test
92 public void testConfigAddStaticLambda() { 99 public void testConfigAddStaticLambda() {
93 - OPC.portType(Port.Type.ODUCLT) 100 + opc.portType(Port.Type.ODUCLT)
94 .portNumberName(PORT_NUMBER) 101 .portNumberName(PORT_NUMBER)
95 .staticLambda(CFG_STATIC_LAMBDA); 102 .staticLambda(CFG_STATIC_LAMBDA);
96 103
97 PortDescription res; 104 PortDescription res;
98 - res = OpticalPortOperator.combine(OPC, N_DESC); 105 + res = oper.combine(CP, N_DESC);
99 assertEquals("Original port name expected", 106 assertEquals("Original port name expected",
100 DESC_PORT_NAME, res.portNumber().name()); 107 DESC_PORT_NAME, res.portNumber().name());
101 assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT)); 108 assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT));
...@@ -105,17 +112,31 @@ public class OpticalPortOperatorTest { ...@@ -105,17 +112,31 @@ public class OpticalPortOperatorTest {
105 112
106 @Test 113 @Test
107 public void testEmptyConfig() { 114 public void testEmptyConfig() {
108 - OPC.portType(Port.Type.ODUCLT) 115 + opc.portType(Port.Type.ODUCLT)
109 .portNumberName(PORT_NUMBER); 116 .portNumberName(PORT_NUMBER);
110 117
111 PortDescription res; 118 PortDescription res;
112 - res = OpticalPortOperator.combine(OPC, N_DESC); 119 + res = oper.combine(CP, N_DESC);
113 assertEquals("Configured port name expected", 120 assertEquals("Configured port name expected",
114 DESC_PORT_NAME, res.portNumber().name()); 121 DESC_PORT_NAME, res.portNumber().name());
115 assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT)); 122 assertEquals(DESC_STATIC_PORT, res.annotations().value(AnnotationKeys.STATIC_PORT));
116 } 123 }
117 124
118 125
126 + private class MockNetworkConfigService
127 + extends NetworkConfigServiceAdapter {
128 +
129 + @Override
130 + public <S, C extends Config<S>> C getConfig(S subject,
131 + Class<C> configClass) {
132 + if (configClass == OpticalPortConfig.class) {
133 + return (C) opc;
134 + }
135 + return null;
136 + }
137 + }
138 +
139 +
119 private class MockCfgDelegate implements ConfigApplyDelegate { 140 private class MockCfgDelegate implements ConfigApplyDelegate {
120 141
121 @Override 142 @Override
......
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.net.config;
17 +
18 +import org.onosproject.net.ConnectPoint;
19 +import org.onosproject.net.DeviceId;
20 +import org.onosproject.net.device.PortDescription;
21 +
22 +import com.google.common.annotations.Beta;
23 +
24 +/**
25 + * {@link ConfigOperator} for Port.
26 + * <p>
27 + * Note: We currently assumes {@link PortConfigOperator}s are commutative.
28 + */
29 +@Beta
30 +public interface PortConfigOperator extends ConfigOperator {
31 +
32 + /**
33 + * Binds {@link NetworkConfigService} to use for retrieving configuration.
34 + *
35 + * @param networkConfigService the service to use
36 + */
37 + void bindService(NetworkConfigService networkConfigService);
38 +
39 +
40 + /**
41 + * Generates a PortDescription containing fields from a PortDescription and
42 + * configuration.
43 + *
44 + * @param cp {@link ConnectPoint} representing the port.
45 + * @param descr input {@link PortDescription}
46 + * @return Combined {@link PortDescription}
47 + */
48 + PortDescription combine(ConnectPoint cp, PortDescription descr);
49 +
50 + /**
51 + * Generates a PortDescription containing fields from a PortDescription and
52 + * configuration.
53 + *
54 + * @param did DeviceId which the port described by {@code descr} resides.
55 + * @param descr input {@link PortDescription}
56 + * @return Combined {@link PortDescription}
57 + */
58 + default PortDescription combine(DeviceId did, PortDescription descr) {
59 + return combine(new ConnectPoint(did, descr.portNumber()), descr);
60 + }
61 +
62 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 + * use this file except in compliance with the License. You may obtain a copy of
6 + * the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 + * License for the specific language governing permissions and limitations under
14 + * the License.
15 + */
16 +package org.onosproject.net.config;
17 +
18 +import org.onosproject.net.ConnectPoint;
19 +
20 +import com.google.common.annotations.Beta;
21 +
22 +/**
23 + * Abstraction of a port operator registry.
24 + */
25 +@Beta
26 +public interface PortConfigOperatorRegistry {
27 +
28 + /**
29 + * Registers {@link PortConfigOperator} instance.
30 + *
31 + * @param portOp {@link PortConfigOperator} instance.
32 + * @param configs {@link Config} class for a Port referred by {@code portOp}
33 + */
34 + void registerPortConfigOperator(PortConfigOperator portOp,
35 + Class<? extends Config<ConnectPoint>>... configs);
36 +
37 + /**
38 + * Unregisters {@link PortConfigOperator} instance.
39 + *
40 + * @param portOp {@link PortConfigOperator} instance.
41 + */
42 + void unregisterPortConfigOperator(PortConfigOperator portOp);
43 +
44 +}
...@@ -105,9 +105,7 @@ ...@@ -105,9 +105,7 @@
105 </dependency> 105 </dependency>
106 106
107 <!-- TODO Remove after decoupling optical --> 107 <!-- TODO Remove after decoupling optical -->
108 - <!-- - DeviceManager.InternalDeviceProviderService#ensureGeneric -->
109 <!-- - OpticalCompilers x4 --> 108 <!-- - OpticalCompilers x4 -->
110 - <!-- - OpticalPortOperator -->
111 <dependency> 109 <dependency>
112 <groupId>org.onosproject</groupId> 110 <groupId>org.onosproject</groupId>
113 <artifactId>onos-optical-model</artifactId> 111 <artifactId>onos-optical-model</artifactId>
......
...@@ -34,7 +34,6 @@ import org.onosproject.net.config.NetworkConfigRegistry; ...@@ -34,7 +34,6 @@ import org.onosproject.net.config.NetworkConfigRegistry;
34 import org.onosproject.net.config.basics.BasicDeviceConfig; 34 import org.onosproject.net.config.basics.BasicDeviceConfig;
35 import org.onosproject.net.config.basics.BasicHostConfig; 35 import org.onosproject.net.config.basics.BasicHostConfig;
36 import org.onosproject.net.config.basics.BasicLinkConfig; 36 import org.onosproject.net.config.basics.BasicLinkConfig;
37 -import org.onosproject.net.config.basics.OpticalPortConfig;
38 import org.onosproject.net.config.basics.SubjectFactories; 37 import org.onosproject.net.config.basics.SubjectFactories;
39 import org.slf4j.Logger; 38 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory; 39 import org.slf4j.LoggerFactory;
...@@ -85,15 +84,6 @@ public class BasicNetworkConfigs implements BasicNetworkConfigService { ...@@ -85,15 +84,6 @@ public class BasicNetworkConfigs implements BasicNetworkConfigService {
85 public BasicLinkConfig createConfig() { 84 public BasicLinkConfig createConfig() {
86 return new BasicLinkConfig(); 85 return new BasicLinkConfig();
87 } 86 }
88 - },
89 - // TODO move this optical specific configuration out to optical app
90 - new ConfigFactory<ConnectPoint, OpticalPortConfig>(CONNECT_POINT_SUBJECT_FACTORY,
91 - OpticalPortConfig.class,
92 - "optical") {
93 - @Override
94 - public OpticalPortConfig createConfig() {
95 - return new OpticalPortConfig();
96 - }
97 } 87 }
98 ); 88 );
99 89
......
...@@ -19,19 +19,22 @@ import java.util.Collection; ...@@ -19,19 +19,22 @@ import java.util.Collection;
19 import java.util.HashSet; 19 import java.util.HashSet;
20 import java.util.List; 20 import java.util.List;
21 import java.util.Objects; 21 import java.util.Objects;
22 +import java.util.Optional;
22 import java.util.Set; 23 import java.util.Set;
23 import java.util.concurrent.CompletableFuture; 24 import java.util.concurrent.CompletableFuture;
25 +import java.util.concurrent.ConcurrentHashMap;
26 +import java.util.concurrent.CopyOnWriteArrayList;
24 import java.util.concurrent.ExecutionException; 27 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.ScheduledExecutorService; 28 import java.util.concurrent.ScheduledExecutorService;
26 import java.util.concurrent.TimeUnit; 29 import java.util.concurrent.TimeUnit;
27 import java.util.stream.Collectors; 30 import java.util.stream.Collectors;
28 -
29 import org.apache.felix.scr.annotations.Activate; 31 import org.apache.felix.scr.annotations.Activate;
30 import org.apache.felix.scr.annotations.Component; 32 import org.apache.felix.scr.annotations.Component;
31 import org.apache.felix.scr.annotations.Deactivate; 33 import org.apache.felix.scr.annotations.Deactivate;
32 import org.apache.felix.scr.annotations.Reference; 34 import org.apache.felix.scr.annotations.Reference;
33 import org.apache.felix.scr.annotations.ReferenceCardinality; 35 import org.apache.felix.scr.annotations.ReferenceCardinality;
34 import org.apache.felix.scr.annotations.Service; 36 import org.apache.felix.scr.annotations.Service;
37 +import org.onlab.util.Tools;
35 import org.onosproject.cluster.ClusterService; 38 import org.onosproject.cluster.ClusterService;
36 import org.onosproject.cluster.NodeId; 39 import org.onosproject.cluster.NodeId;
37 import org.onosproject.mastership.MastershipEvent; 40 import org.onosproject.mastership.MastershipEvent;
...@@ -46,11 +49,13 @@ import org.onosproject.net.DeviceId; ...@@ -46,11 +49,13 @@ import org.onosproject.net.DeviceId;
46 import org.onosproject.net.MastershipRole; 49 import org.onosproject.net.MastershipRole;
47 import org.onosproject.net.Port; 50 import org.onosproject.net.Port;
48 import org.onosproject.net.PortNumber; 51 import org.onosproject.net.PortNumber;
52 +import org.onosproject.net.config.Config;
49 import org.onosproject.net.config.NetworkConfigEvent; 53 import org.onosproject.net.config.NetworkConfigEvent;
50 import org.onosproject.net.config.NetworkConfigListener; 54 import org.onosproject.net.config.NetworkConfigListener;
51 import org.onosproject.net.config.NetworkConfigService; 55 import org.onosproject.net.config.NetworkConfigService;
56 +import org.onosproject.net.config.PortConfigOperator;
57 +import org.onosproject.net.config.PortConfigOperatorRegistry;
52 import org.onosproject.net.config.basics.BasicDeviceConfig; 58 import org.onosproject.net.config.basics.BasicDeviceConfig;
53 -import org.onosproject.net.config.basics.OpticalPortConfig;
54 import org.onosproject.net.device.DefaultPortDescription; 59 import org.onosproject.net.device.DefaultPortDescription;
55 import org.onosproject.net.device.DeviceAdminService; 60 import org.onosproject.net.device.DeviceAdminService;
56 import org.onosproject.net.device.DeviceDescription; 61 import org.onosproject.net.device.DeviceDescription;
...@@ -62,29 +67,23 @@ import org.onosproject.net.device.DeviceProviderService; ...@@ -62,29 +67,23 @@ import org.onosproject.net.device.DeviceProviderService;
62 import org.onosproject.net.device.DeviceService; 67 import org.onosproject.net.device.DeviceService;
63 import org.onosproject.net.device.DeviceStore; 68 import org.onosproject.net.device.DeviceStore;
64 import org.onosproject.net.device.DeviceStoreDelegate; 69 import org.onosproject.net.device.DeviceStoreDelegate;
65 -import org.onosproject.net.device.OchPortDescription;
66 -import org.onosproject.net.device.OduCltPortDescription;
67 -import org.onosproject.net.device.OmsPortDescription;
68 -import org.onosproject.net.device.OtuPortDescription;
69 import org.onosproject.net.device.PortDescription; 70 import org.onosproject.net.device.PortDescription;
70 import org.onosproject.net.device.PortStatistics; 71 import org.onosproject.net.device.PortStatistics;
71 -import org.onosproject.net.optical.device.OmsPortHelper;
72 -import org.onosproject.net.optical.device.OtuPortHelper;
73 import org.onosproject.net.provider.AbstractListenerProviderRegistry; 72 import org.onosproject.net.provider.AbstractListenerProviderRegistry;
74 import org.onosproject.net.provider.AbstractProviderService; 73 import org.onosproject.net.provider.AbstractProviderService;
75 -import org.onosproject.net.provider.Provider;
76 import org.slf4j.Logger; 74 import org.slf4j.Logger;
77 75
76 +import com.google.common.collect.Multimap;
78 import com.google.common.util.concurrent.Futures; 77 import com.google.common.util.concurrent.Futures;
79 78
80 import static com.google.common.base.Preconditions.checkNotNull; 79 import static com.google.common.base.Preconditions.checkNotNull;
80 +import static com.google.common.collect.Multimaps.newListMultimap;
81 +import static com.google.common.collect.Multimaps.synchronizedListMultimap;
81 import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; 82 import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
82 import static org.onlab.util.Tools.groupedThreads; 83 import static org.onlab.util.Tools.groupedThreads;
83 import static org.onosproject.net.MastershipRole.MASTER; 84 import static org.onosproject.net.MastershipRole.MASTER;
84 import static org.onosproject.net.MastershipRole.NONE; 85 import static org.onosproject.net.MastershipRole.NONE;
85 import static org.onosproject.net.MastershipRole.STANDBY; 86 import static org.onosproject.net.MastershipRole.STANDBY;
86 -import static org.onosproject.net.optical.device.OchPortHelper.ochPortDescription;
87 -import static org.onosproject.net.optical.device.OduCltPortHelper.oduCltPortDescription;
88 import static org.onosproject.security.AppGuard.checkPermission; 87 import static org.onosproject.security.AppGuard.checkPermission;
89 import static org.onosproject.security.AppPermission.Type.DEVICE_READ; 88 import static org.onosproject.security.AppPermission.Type.DEVICE_READ;
90 import static org.slf4j.LoggerFactory.getLogger; 89 import static org.slf4j.LoggerFactory.getLogger;
...@@ -96,7 +95,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -96,7 +95,7 @@ import static org.slf4j.LoggerFactory.getLogger;
96 @Service 95 @Service
97 public class DeviceManager 96 public class DeviceManager
98 extends AbstractListenerProviderRegistry<DeviceEvent, DeviceListener, DeviceProvider, DeviceProviderService> 97 extends AbstractListenerProviderRegistry<DeviceEvent, DeviceListener, DeviceProvider, DeviceProviderService>
99 - implements DeviceService, DeviceAdminService, DeviceProviderRegistry { 98 + implements DeviceService, DeviceAdminService, DeviceProviderRegistry, PortConfigOperatorRegistry {
100 99
101 private static final String DEVICE_ID_NULL = "Device ID cannot be null"; 100 private static final String DEVICE_ID_NULL = "Device ID cannot be null";
102 private static final String PORT_NUMBER_NULL = "Port number cannot be null"; 101 private static final String PORT_NUMBER_NULL = "Port number cannot be null";
...@@ -130,6 +129,20 @@ public class DeviceManager ...@@ -130,6 +129,20 @@ public class DeviceManager
130 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 129 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
131 protected NetworkConfigService networkConfigService; 130 protected NetworkConfigService networkConfigService;
132 131
132 +
133 + /**
134 + * List of all registered PortConfigOperator.
135 + */
136 + private final List<PortConfigOperator> portOps = new CopyOnWriteArrayList<>();
137 +
138 + /**
139 + * Index to look up PortConfigOperator from Config each PortConfigOperator uses.
140 + */
141 + private final Multimap<Class<? extends Config<ConnectPoint>>, PortConfigOperator> portOpsIndex
142 + = synchronizedListMultimap(
143 + newListMultimap(new ConcurrentHashMap<>(), CopyOnWriteArrayList::new));
144 +
145 +
133 @Activate 146 @Activate
134 public void activate() { 147 public void activate() {
135 backgroundService = newSingleThreadScheduledExecutor( 148 backgroundService = newSingleThreadScheduledExecutor(
...@@ -445,60 +458,6 @@ public class DeviceManager ...@@ -445,60 +458,6 @@ public class DeviceManager
445 } 458 }
446 } 459 }
447 460
448 - /**
449 - * Transforms optical specific PortDescription to generic PortDescription.
450 - *
451 - * @param descr PortDescription
452 - * @return generic PortDescription
453 - * @deprecated in Goldeneye (1.6.0)
454 - */
455 - @Deprecated
456 - private PortDescription ensureGeneric(PortDescription descr) {
457 - switch (descr.type()) {
458 - case OCH:
459 - if (descr instanceof OchPortDescription) {
460 - OchPortDescription och = (OchPortDescription) descr;
461 - return ochPortDescription(och,
462 - och.signalType(),
463 - och.isTunable(),
464 - och.lambda(),
465 - och.annotations());
466 - }
467 - break;
468 - case ODUCLT:
469 - if (descr instanceof OduCltPortDescription) {
470 - OduCltPortDescription clt = (OduCltPortDescription) descr;
471 - return oduCltPortDescription(clt,
472 - clt.signalType(),
473 - clt.annotations());
474 - }
475 - break;
476 - case OMS:
477 - if (descr instanceof OmsPortDescription) {
478 - OmsPortDescription oms = (OmsPortDescription) descr;
479 - return OmsPortHelper.omsPortDescription(oms,
480 - oms.minFrequency(),
481 - oms.maxFrequency(),
482 - oms.grid(),
483 - oms.annotations());
484 - }
485 - break;
486 - case OTU:
487 - if (descr instanceof OtuPortDescription) {
488 - OtuPortDescription otu = (OtuPortDescription) descr;
489 - return OtuPortHelper.otuPortDescription(otu,
490 - otu.signalType(),
491 - otu.annotations());
492 - }
493 - break;
494 -
495 - default:
496 - // no-op
497 - break;
498 - }
499 - return descr;
500 - }
501 -
502 @Override 461 @Override
503 public void updatePorts(DeviceId deviceId, 462 public void updatePorts(DeviceId deviceId,
504 List<PortDescription> portDescriptions) { 463 List<PortDescription> portDescriptions) {
...@@ -512,8 +471,7 @@ public class DeviceManager ...@@ -512,8 +471,7 @@ public class DeviceManager
512 return; 471 return;
513 } 472 }
514 portDescriptions = portDescriptions.stream() 473 portDescriptions = portDescriptions.stream()
515 - .map(e -> consolidate(deviceId, e)) 474 + .map(e -> applyAllPortOps(deviceId, e))
516 - .map(this::ensureGeneric)
517 .collect(Collectors.toList()); 475 .collect(Collectors.toList());
518 List<DeviceEvent> events = store.updatePorts(this.provider().id(), 476 List<DeviceEvent> events = store.updatePorts(this.provider().id(),
519 deviceId, portDescriptions); 477 deviceId, portDescriptions);
...@@ -552,30 +510,16 @@ public class DeviceManager ...@@ -552,30 +510,16 @@ public class DeviceManager
552 portDescription.isEnabled()); 510 portDescription.isEnabled());
553 } 511 }
554 512
555 - portDescription = consolidate(deviceId, portDescription); 513 + portDescription = applyAllPortOps(deviceId, portDescription);
556 final DeviceEvent event = store.updatePortStatus(this.provider().id(), 514 final DeviceEvent event = store.updatePortStatus(this.provider().id(),
557 deviceId, 515 deviceId,
558 - ensureGeneric(portDescription)); 516 + portDescription);
559 if (event != null) { 517 if (event != null) {
560 log.info("Device {} port {} status changed", deviceId, event.port().number()); 518 log.info("Device {} port {} status changed", deviceId, event.port().number());
561 post(event); 519 post(event);
562 } 520 }
563 } 521 }
564 522
565 - // merges the appropriate PortConfig with the description.
566 - private PortDescription consolidate(DeviceId did, PortDescription desc) {
567 - switch (desc.type()) {
568 - case COPPER:
569 - case VIRTUAL:
570 - return desc;
571 - default:
572 - // TODO: add plugin mechanism in order to decouple this
573 - OpticalPortConfig opc = networkConfigService.getConfig(
574 - new ConnectPoint(did, desc.portNumber()), OpticalPortConfig.class);
575 - return OpticalPortOperator.combine(opc, desc);
576 - }
577 - }
578 -
579 @Override 523 @Override
580 public void receivedRoleReply(DeviceId deviceId, MastershipRole requested, 524 public void receivedRoleReply(DeviceId deviceId, MastershipRole requested,
581 MastershipRole response) { 525 MastershipRole response) {
...@@ -835,7 +779,7 @@ public class DeviceManager ...@@ -835,7 +779,7 @@ public class DeviceManager
835 return (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED 779 return (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED
836 || event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) 780 || event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)
837 && (event.configClass().equals(BasicDeviceConfig.class) 781 && (event.configClass().equals(BasicDeviceConfig.class)
838 - || event.configClass().equals(OpticalPortConfig.class)); 782 + || portOpsIndex.containsKey(event.configClass()));
839 } 783 }
840 784
841 @Override 785 @Override
...@@ -857,20 +801,17 @@ public class DeviceManager ...@@ -857,20 +801,17 @@ public class DeviceManager
857 } 801 }
858 } 802 }
859 } 803 }
860 - if (event.configClass().equals(OpticalPortConfig.class)) { 804 + if (portOpsIndex.containsKey(event.configClass())) {
861 ConnectPoint cpt = (ConnectPoint) event.subject(); 805 ConnectPoint cpt = (ConnectPoint) event.subject();
862 DeviceId did = cpt.deviceId(); 806 DeviceId did = cpt.deviceId();
863 - Provider provider = getProvider(did); 807 +
864 - Port dpt = getPort(did, cpt.port()); 808 + // Note: assuming PortOperator can modify existing port,
865 - 809 + // but cannot add new port purely from Config.
866 - if (dpt != null && provider != null) { 810 + de = Optional.ofNullable(getProvider(did))
867 - OpticalPortConfig opc = networkConfigService.getConfig(cpt, OpticalPortConfig.class); 811 + .map(provider -> store.getPortDescription(provider.id(), did, cpt.port()))
868 - PortDescription desc = store.getPortDescription(provider.id(), did, cpt.port()); 812 + .map(desc -> applyAllPortOps(cpt, desc))
869 - desc = OpticalPortOperator.combine(opc, desc); 813 + .map(desc -> store.updatePortStatus(getProvider(did).id(), did, desc))
870 - if (desc != null) { 814 + .orElse(null);
871 - de = store.updatePortStatus(getProvider(did).id(), did, desc);
872 - }
873 - }
874 } 815 }
875 816
876 if (de != null) { 817 if (de != null) {
...@@ -888,4 +829,78 @@ public class DeviceManager ...@@ -888,4 +829,78 @@ public class DeviceManager
888 } 829 }
889 } 830 }
890 831
832 + @Override
833 + @SafeVarargs
834 + public final void registerPortConfigOperator(PortConfigOperator portOp,
835 + Class<? extends Config<ConnectPoint>>...configs) {
836 + checkNotNull(portOp);
837 +
838 + portOp.bindService(networkConfigService);
839 +
840 + // update both portOpsIndex and portOps
841 + synchronized (portOpsIndex) {
842 + for (Class<? extends Config<ConnectPoint>> config : configs) {
843 + portOpsIndex.put(config, portOp);
844 + }
845 +
846 + portOps.add(portOp);
847 + }
848 +
849 + // TODO: Should we be applying to all existing Ports?
850 + Tools.stream(store.getAvailableDevices())
851 + .map(Device::id)
852 + .filter(mastershipService::isLocalMaster)
853 + // for each locally managed Device, update all port descriptions
854 + .map(did -> {
855 + List<PortDescription> pds
856 + = store.getPortDescriptions(getProvider(did).id(), did)
857 + .map(pdesc -> applyAllPortOps(did, pdesc))
858 + .collect(Collectors.toList());
859 + return store.updatePorts(getProvider(did).id(), did, pds);
860 + })
861 + // ..and port port update event if necessary
862 + .forEach(evts -> evts.forEach(this::post));
863 + }
864 +
865 + @Override
866 + public void unregisterPortConfigOperator(PortConfigOperator portOp) {
867 + checkNotNull(portOp);
868 +
869 +
870 + // remove all portOp
871 + synchronized (portOpsIndex) {
872 + portOps.remove(portOp);
873 +
874 + // had to do this since COWArrayList iterator doesn't support remove
875 + portOpsIndex.keySet().forEach(key -> portOpsIndex.remove(key, portOp));
876 + }
877 +
878 + }
879 +
880 + /**
881 + * Merges the appropriate PortConfig with the description.
882 + *
883 + * @param did ID of the Device where the port is attached
884 + * @param desc {@link PortDescription}
885 + * @return merged {@link PortDescription}
886 + */
887 + private PortDescription applyAllPortOps(DeviceId did, PortDescription desc) {
888 + return applyAllPortOps(new ConnectPoint(did, desc.portNumber()), desc);
889 + }
890 +
891 + /**
892 + * Merges the appropriate PortConfig with the description.
893 + *
894 + * @param cpt ConnectPoint where the port is attached
895 + * @param desc {@link PortDescription}
896 + * @return merged {@link PortDescription}
897 + */
898 + private PortDescription applyAllPortOps(ConnectPoint cpt, PortDescription desc) {
899 + PortDescription work = desc;
900 + for (PortConfigOperator portOp : portOps) {
901 + work = portOp.combine(cpt, work);
902 + }
903 + return work;
904 + }
905 +
891 } 906 }
......