Jonathan Hart

Move address-bindings config to new config system

Change-Id: I6d87ddbf98789dbe8355c453a3263f50fbc5d99c
...@@ -63,7 +63,7 @@ public class NetworkConfigCommand extends AbstractShellCommand { ...@@ -63,7 +63,7 @@ public class NetworkConfigCommand extends AbstractShellCommand {
63 if (isNullOrEmpty(configKey)) { 63 if (isNullOrEmpty(configKey)) {
64 addSubject(root, s); 64 addSubject(root, s);
65 } else { 65 } else {
66 - root = getSubjectConfig(getConfig(s, configKey)); 66 + root = getSubjectConfig(getConfig(s, subjectKey, configKey));
67 } 67 }
68 } 68 }
69 } 69 }
...@@ -93,8 +93,8 @@ public class NetworkConfigCommand extends AbstractShellCommand { ...@@ -93,8 +93,8 @@ public class NetworkConfigCommand extends AbstractShellCommand {
93 return config != null ? config.node() : null; 93 return config != null ? config.node() : null;
94 } 94 }
95 95
96 - private Config getConfig(Object s, String ck) { 96 + private Config getConfig(Object s, String subjectKey, String ck) {
97 - Class<? extends Config> configClass = service.getConfigClass(ck); 97 + Class<? extends Config> configClass = service.getConfigClass(subjectKey, ck);
98 return configClass != null ? service.getConfig(s, configClass) : null; 98 return configClass != null ? service.getConfig(s, configClass) : null;
99 } 99 }
100 100
......
...@@ -15,10 +15,7 @@ ...@@ -15,10 +15,7 @@
15 */ 15 */
16 package org.onosproject.cli.net; 16 package org.onosproject.cli.net;
17 17
18 -import java.util.Collections; 18 +import com.google.common.collect.Lists;
19 -import java.util.List;
20 -import java.util.Set;
21 -
22 import org.apache.karaf.shell.commands.Command; 19 import org.apache.karaf.shell.commands.Command;
23 import org.onosproject.cli.AbstractShellCommand; 20 import org.onosproject.cli.AbstractShellCommand;
24 import org.onosproject.cli.Comparators; 21 import org.onosproject.cli.Comparators;
...@@ -26,7 +23,9 @@ import org.onosproject.net.host.HostService; ...@@ -26,7 +23,9 @@ import org.onosproject.net.host.HostService;
26 import org.onosproject.net.host.InterfaceIpAddress; 23 import org.onosproject.net.host.InterfaceIpAddress;
27 import org.onosproject.net.host.PortAddresses; 24 import org.onosproject.net.host.PortAddresses;
28 25
29 -import com.google.common.collect.Lists; 26 +import java.util.Collections;
27 +import java.util.List;
28 +import java.util.Set;
30 29
31 /** 30 /**
32 * Lists all configured address port bindings. 31 * Lists all configured address port bindings.
......
...@@ -15,11 +15,12 @@ ...@@ -15,11 +15,12 @@
15 */ 15 */
16 package org.onosproject.net.host; 16 package org.onosproject.net.host;
17 17
18 -import java.util.Objects;
19 import org.onlab.packet.IpAddress; 18 import org.onlab.packet.IpAddress;
20 import org.onlab.packet.IpPrefix; 19 import org.onlab.packet.IpPrefix;
21 20
22 -import static com.google.common.base.MoreObjects.toStringHelper; 21 +import java.util.Objects;
22 +
23 +import static com.google.common.base.Preconditions.checkArgument;
23 import static com.google.common.base.Preconditions.checkNotNull; 24 import static com.google.common.base.Preconditions.checkNotNull;
24 25
25 /** 26 /**
...@@ -138,6 +139,24 @@ public class InterfaceIpAddress { ...@@ -138,6 +139,24 @@ public class InterfaceIpAddress {
138 return peerAddress; 139 return peerAddress;
139 } 140 }
140 141
142 + /**
143 + * Converts a CIDR string literal to an interface IP address.
144 + * E.g. 10.0.0.1/24
145 + *
146 + * @param value an IP address value in string form
147 + * @return an interface IP address
148 + * @throws IllegalArgumentException if the argument is invalid
149 + */
150 + public static InterfaceIpAddress valueOf(String value) {
151 + String[] splits = value.split("/");
152 + checkArgument(splits.length == 2, "Invalid IP address and prefix length format");
153 +
154 + // NOTE: IpPrefix will mask-out the bits after the prefix length.
155 + IpPrefix subnet = IpPrefix.valueOf(value);
156 + IpAddress addr = IpAddress.valueOf(splits[0]);
157 + return new InterfaceIpAddress(addr, subnet);
158 + }
159 +
141 @Override 160 @Override
142 public boolean equals(Object other) { 161 public boolean equals(Object other) {
143 if (other == this) { 162 if (other == this) {
...@@ -163,10 +182,11 @@ public class InterfaceIpAddress { ...@@ -163,10 +182,11 @@ public class InterfaceIpAddress {
163 182
164 @Override 183 @Override
165 public String toString() { 184 public String toString() {
166 - return toStringHelper(this).add("ipAddress", ipAddress) 185 + /*return toStringHelper(this).add("ipAddress", ipAddress)
167 .add("subnetAddress", subnetAddress) 186 .add("subnetAddress", subnetAddress)
168 .add("broadcastAddress", broadcastAddress) 187 .add("broadcastAddress", broadcastAddress)
169 .add("peerAddress", peerAddress) 188 .add("peerAddress", peerAddress)
170 - .omitNullValues().toString(); 189 + .omitNullValues().toString();*/
190 + return ipAddress.toString() + "/" + subnetAddress.prefixLength();
171 } 191 }
172 } 192 }
......
...@@ -54,22 +54,28 @@ public class InterfaceIpAddressTest { ...@@ -54,22 +54,28 @@ public class InterfaceIpAddressTest {
54 // Regular interface address with default broadcast address 54 // Regular interface address with default broadcast address
55 fromAddr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS); 55 fromAddr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS);
56 toAddr = new InterfaceIpAddress(fromAddr); 56 toAddr = new InterfaceIpAddress(fromAddr);
57 - assertThat(toAddr.toString(), 57 + assertThat(toAddr.ipAddress(), is(fromAddr.ipAddress()));
58 - is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16}")); 58 + assertThat(toAddr.subnetAddress(), is(fromAddr.subnetAddress()));
59 + assertThat(toAddr.broadcastAddress(), is(fromAddr.broadcastAddress()));
60 + assertThat(toAddr.peerAddress(), is(fromAddr.peerAddress()));
59 61
60 // Interface address with non-default broadcast address 62 // Interface address with non-default broadcast address
61 fromAddr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, 63 fromAddr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS,
62 BROADCAST_ADDRESS); 64 BROADCAST_ADDRESS);
63 toAddr = new InterfaceIpAddress(fromAddr); 65 toAddr = new InterfaceIpAddress(fromAddr);
64 - assertThat(toAddr.toString(), 66 + assertThat(toAddr.ipAddress(), is(fromAddr.ipAddress()));
65 - is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16, broadcastAddress=1.2.0.255}")); 67 + assertThat(toAddr.subnetAddress(), is(fromAddr.subnetAddress()));
68 + assertThat(toAddr.broadcastAddress(), is(fromAddr.broadcastAddress()));
69 + assertThat(toAddr.peerAddress(), is(fromAddr.peerAddress()));
66 70
67 // Point-to-point address with peer IP address 71 // Point-to-point address with peer IP address
68 fromAddr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null, 72 fromAddr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null,
69 PEER_ADDRESS); 73 PEER_ADDRESS);
70 toAddr = new InterfaceIpAddress(fromAddr); 74 toAddr = new InterfaceIpAddress(fromAddr);
71 - assertThat(toAddr.toString(), 75 + assertThat(toAddr.ipAddress(), is(fromAddr.ipAddress()));
72 - is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16, peerAddress=5.6.7.8}")); 76 + assertThat(toAddr.subnetAddress(), is(fromAddr.subnetAddress()));
77 + assertThat(toAddr.broadcastAddress(), is(fromAddr.broadcastAddress()));
78 + assertThat(toAddr.peerAddress(), is(fromAddr.peerAddress()));
73 } 79 }
74 80
75 /** 81 /**
...@@ -89,8 +95,10 @@ public class InterfaceIpAddressTest { ...@@ -89,8 +95,10 @@ public class InterfaceIpAddressTest {
89 public void testConstructorForDefaultBroadcastAddress() { 95 public void testConstructorForDefaultBroadcastAddress() {
90 InterfaceIpAddress addr = 96 InterfaceIpAddress addr =
91 new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS); 97 new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS);
92 - assertThat(addr.toString(), 98 + assertThat(addr.ipAddress(), is(IP_ADDRESS));
93 - is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16}")); 99 + assertThat(addr.subnetAddress(), is(SUBNET_ADDRESS));
100 + assertThat(addr.broadcastAddress(), nullValue());
101 + assertThat(addr.peerAddress(), nullValue());
94 } 102 }
95 103
96 /** 104 /**
...@@ -102,8 +110,11 @@ public class InterfaceIpAddressTest { ...@@ -102,8 +110,11 @@ public class InterfaceIpAddressTest {
102 InterfaceIpAddress addr = 110 InterfaceIpAddress addr =
103 new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, 111 new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS,
104 BROADCAST_ADDRESS); 112 BROADCAST_ADDRESS);
105 - assertThat(addr.toString(), 113 +
106 - is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16, broadcastAddress=1.2.0.255}")); 114 + assertThat(addr.ipAddress(), is(IP_ADDRESS));
115 + assertThat(addr.subnetAddress(), is(SUBNET_ADDRESS));
116 + assertThat(addr.broadcastAddress(), is(BROADCAST_ADDRESS));
117 + assertThat(addr.peerAddress(), nullValue());
107 } 118 }
108 119
109 /** 120 /**
...@@ -115,8 +126,11 @@ public class InterfaceIpAddressTest { ...@@ -115,8 +126,11 @@ public class InterfaceIpAddressTest {
115 InterfaceIpAddress addr = 126 InterfaceIpAddress addr =
116 new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null, 127 new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null,
117 PEER_ADDRESS); 128 PEER_ADDRESS);
118 - assertThat(addr.toString(), 129 +
119 - is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16, peerAddress=5.6.7.8}")); 130 + assertThat(addr.ipAddress(), is(IP_ADDRESS));
131 + assertThat(addr.subnetAddress(), is(SUBNET_ADDRESS));
132 + assertThat(addr.broadcastAddress(), nullValue());
133 + assertThat(addr.peerAddress(), is(PEER_ADDRESS));
120 } 134 }
121 135
122 /** 136 /**
...@@ -229,28 +243,4 @@ public class InterfaceIpAddressTest { ...@@ -229,28 +243,4 @@ public class InterfaceIpAddressTest {
229 assertThat(addr3, is(not(addr4))); 243 assertThat(addr3, is(not(addr4)));
230 } 244 }
231 245
232 - /**
233 - * Tests object string representation.
234 - */
235 - @Test
236 - public void testToString() {
237 - InterfaceIpAddress addr;
238 -
239 - // Regular interface address with default broadcast address
240 - addr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS);
241 - assertThat(addr.toString(),
242 - is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16}"));
243 -
244 - // Interface address with non-default broadcast address
245 - addr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS,
246 - BROADCAST_ADDRESS);
247 - assertThat(addr.toString(),
248 - is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16, broadcastAddress=1.2.0.255}"));
249 -
250 - // Point-to-point address with peer IP address
251 - addr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null,
252 - PEER_ADDRESS);
253 - assertThat(addr.toString(),
254 - is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16, peerAddress=5.6.7.8}"));
255 - }
256 } 246 }
......
...@@ -151,6 +151,33 @@ public abstract class Config<S> { ...@@ -151,6 +151,33 @@ public abstract class Config<S> {
151 } 151 }
152 152
153 /** 153 /**
154 + * Gets the specified property as an integer.
155 + *
156 + * @param name property name
157 + * @param defaultValue default value if property not set
158 + * @return property value or default value
159 + */
160 + protected int get(String name, int defaultValue) {
161 + return node.path(name).asInt(defaultValue);
162 + }
163 +
164 + /**
165 + * Sets the specified property as an integer or clears it if null value given.
166 + *
167 + * @param name property name
168 + * @param value new value or null to clear the property
169 + * @return self
170 + */
171 + protected Config<S> setOrClear(String name, Integer value) {
172 + if (value != null) {
173 + node.put(name, value.intValue());
174 + } else {
175 + node.remove(name);
176 + }
177 + return this;
178 + }
179 +
180 + /**
154 * Gets the specified property as a long. 181 * Gets the specified property as a long.
155 * 182 *
156 * @param name property name 183 * @param name property name
...@@ -231,4 +258,5 @@ public abstract class Config<S> { ...@@ -231,4 +258,5 @@ public abstract class Config<S> {
231 } 258 }
232 return this; 259 return this;
233 } 260 }
261 +
234 } 262 }
......
...@@ -58,7 +58,7 @@ public interface NetworkConfigService { ...@@ -58,7 +58,7 @@ public interface NetworkConfigService {
58 * @param configKey subject class name 58 * @param configKey subject class name
59 * @return subject class 59 * @return subject class
60 */ 60 */
61 - Class<? extends Config> getConfigClass(String configKey); 61 + Class<? extends Config> getConfigClass(String subjectKey, String configKey);
62 62
63 /** 63 /**
64 * Returns the set of subjects for which some configuration is available. 64 * Returns the set of subjects for which some configuration is available.
......
1 +/*
2 + * Copyright 2015 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 +
17 +package org.onosproject.incubator.net.config.basics;
18 +
19 +import com.fasterxml.jackson.databind.JsonNode;
20 +import com.fasterxml.jackson.databind.node.ArrayNode;
21 +import com.google.common.collect.Sets;
22 +import org.onlab.packet.MacAddress;
23 +import org.onlab.packet.VlanId;
24 +import org.onosproject.incubator.net.config.Config;
25 +import org.onosproject.net.ConnectPoint;
26 +import org.onosproject.net.host.InterfaceIpAddress;
27 +
28 +import java.util.Iterator;
29 +import java.util.Set;
30 +
31 +/**
32 + * Basic configuration for a port on a device.
33 + */
34 +public class BasicPortConfig extends Config<ConnectPoint> {
35 + public static final String IPS = "ips";
36 + public static final String MAC = "mac";
37 + public static final String VLAN = "vlan";
38 +
39 + /**
40 + * Returns the set of IP addresses assigned to the port.
41 + *
42 + * @return set ip IP addresses
43 + */
44 + public Set<InterfaceIpAddress> ips() {
45 + Set<InterfaceIpAddress> ips = Sets.newHashSet();
46 +
47 + JsonNode ipsNode = node.get(IPS);
48 + ipsNode.forEach(jsonNode -> ips.add(InterfaceIpAddress.valueOf(jsonNode.asText())));
49 +
50 + return ips;
51 + }
52 +
53 + /**
54 + * Adds an IP address to configuration of the port.
55 + *
56 + * @param ip ip address to add
57 + * @return this
58 + */
59 + public BasicPortConfig addIp(InterfaceIpAddress ip) {
60 + ArrayNode ipsNode = (ArrayNode) node.get(IPS);
61 + if (ipsNode == null) {
62 + ipsNode = node.putArray(IPS);
63 + }
64 +
65 + // Check if the value is already there
66 + if (ipsNode.findValue(ip.toString()) != null) {
67 + ipsNode.add(ip.toString());
68 + }
69 +
70 + return this;
71 + }
72 +
73 + /**
74 + * Removes an IP address from the configuration of the port.
75 + *
76 + * @param ip ip address to remove
77 + * @return this
78 + */
79 + public BasicPortConfig removeIp(InterfaceIpAddress ip) {
80 + ArrayNode ipsNode = (ArrayNode) node.get(IPS);
81 +
82 + if (ipsNode != null) {
83 + if (ipsNode.size() == 1) {
84 + node.remove(IPS);
85 + } else {
86 + Iterator<JsonNode> it = ipsNode.iterator();
87 + while (it.hasNext()) {
88 + if (it.next().asText().equals(ip.toString())) {
89 + it.remove();
90 + break;
91 + }
92 + }
93 + }
94 + }
95 +
96 + return this;
97 + }
98 +
99 + /**
100 + * Clear all IP addresses from the configuration.
101 + *
102 + * @return this
103 + */
104 + public BasicPortConfig clearIps() {
105 + node.remove(IPS);
106 + return this;
107 + }
108 +
109 + /**
110 + * Returns the MAC address configured on the port.
111 + *
112 + * @return MAC address
113 + */
114 + public MacAddress mac() {
115 + JsonNode macNode = node.get(MAC);
116 + if (macNode == null) {
117 + return null;
118 + }
119 +
120 + return MacAddress.valueOf(macNode.asText());
121 + }
122 +
123 + /**
124 + * Sets the MAC address configured on the port.
125 + *
126 + * @param mac MAC address
127 + * @return this
128 + */
129 + public BasicPortConfig mac(MacAddress mac) {
130 + String macString = (mac == null) ? null : mac.toString();
131 + return (BasicPortConfig) setOrClear(MAC, macString);
132 + }
133 +
134 + /**
135 + * Returns the VLAN configured on the port.
136 + *
137 + * @return VLAN ID
138 + */
139 + public VlanId vlan() {
140 + JsonNode macNode = node.get(VLAN);
141 + if (macNode == null) {
142 + return null;
143 + }
144 +
145 + return VlanId.vlanId(Short.parseShort(macNode.asText()));
146 + }
147 +
148 + /**
149 + * Sets the VLAN configured on the port.
150 + *
151 + * @param vlan VLAN ID
152 + * @return this
153 + */
154 + public BasicPortConfig vlan(VlanId vlan) {
155 + Integer vlanId = (vlan == null) ? null : Integer.valueOf(vlan.toShort());
156 + return (BasicPortConfig) setOrClear(VLAN, vlanId);
157 + }
158 +}
...@@ -50,6 +50,14 @@ public final class SubjectFactories { ...@@ -50,6 +50,14 @@ public final class SubjectFactories {
50 } 50 }
51 }; 51 };
52 52
53 + public static final SubjectFactory<ConnectPoint> CONNECT_POINT_SUBJECT_FACTORY =
54 + new SubjectFactory<ConnectPoint>(ConnectPoint.class, "ports") {
55 + @Override
56 + public ConnectPoint createSubject(String key) {
57 + return ConnectPoint.deviceConnectPoint(key);
58 + }
59 + };
60 +
53 public static final SubjectFactory<HostId> HOST_SUBJECT_FACTORY = 61 public static final SubjectFactory<HostId> HOST_SUBJECT_FACTORY =
54 new SubjectFactory<HostId>(HostId.class, "hosts") { 62 new SubjectFactory<HostId>(HostId.class, "hosts") {
55 @Override 63 @Override
......
...@@ -26,6 +26,8 @@ import org.onosproject.incubator.net.config.NetworkConfigRegistry; ...@@ -26,6 +26,8 @@ import org.onosproject.incubator.net.config.NetworkConfigRegistry;
26 import org.onosproject.incubator.net.config.basics.BasicDeviceConfig; 26 import org.onosproject.incubator.net.config.basics.BasicDeviceConfig;
27 import org.onosproject.incubator.net.config.basics.BasicHostConfig; 27 import org.onosproject.incubator.net.config.basics.BasicHostConfig;
28 import org.onosproject.incubator.net.config.basics.BasicLinkConfig; 28 import org.onosproject.incubator.net.config.basics.BasicLinkConfig;
29 +import org.onosproject.incubator.net.config.basics.BasicPortConfig;
30 +import org.onosproject.net.ConnectPoint;
29 import org.onosproject.net.DeviceId; 31 import org.onosproject.net.DeviceId;
30 import org.onosproject.net.HostId; 32 import org.onosproject.net.HostId;
31 import org.onosproject.net.LinkKey; 33 import org.onosproject.net.LinkKey;
...@@ -34,7 +36,10 @@ import org.slf4j.LoggerFactory; ...@@ -34,7 +36,10 @@ import org.slf4j.LoggerFactory;
34 36
35 import java.util.Set; 37 import java.util.Set;
36 38
37 -import static org.onosproject.incubator.net.config.basics.SubjectFactories.*; 39 +import static org.onosproject.incubator.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY;
40 +import static org.onosproject.incubator.net.config.basics.SubjectFactories.DEVICE_SUBJECT_FACTORY;
41 +import static org.onosproject.incubator.net.config.basics.SubjectFactories.HOST_SUBJECT_FACTORY;
42 +import static org.onosproject.incubator.net.config.basics.SubjectFactories.LINK_SUBJECT_FACTORY;
38 43
39 /** 44 /**
40 * Component for registration of builtin basic network configurations. 45 * Component for registration of builtin basic network configurations.
...@@ -53,6 +58,14 @@ public class BasicNetworkConfigs { ...@@ -53,6 +58,14 @@ public class BasicNetworkConfigs {
53 return new BasicDeviceConfig(); 58 return new BasicDeviceConfig();
54 } 59 }
55 }, 60 },
61 + new ConfigFactory<ConnectPoint, BasicPortConfig>(CONNECT_POINT_SUBJECT_FACTORY,
62 + BasicPortConfig.class,
63 + "basic") {
64 + @Override
65 + public BasicPortConfig createConfig() {
66 + return new BasicPortConfig();
67 + }
68 + },
56 new ConfigFactory<HostId, BasicHostConfig>(HOST_SUBJECT_FACTORY, 69 new ConfigFactory<HostId, BasicHostConfig>(HOST_SUBJECT_FACTORY,
57 BasicHostConfig.class, 70 BasicHostConfig.class,
58 "basic") { 71 "basic") {
......
...@@ -86,13 +86,15 @@ public class NetworkConfigLoader { ...@@ -86,13 +86,15 @@ public class NetworkConfigLoader {
86 SubjectFactory subjectFactory) { 86 SubjectFactory subjectFactory) {
87 classNode.fieldNames().forEachRemaining(s -> 87 classNode.fieldNames().forEachRemaining(s ->
88 consumeSubjectJson(service, (ObjectNode) classNode.path(s), 88 consumeSubjectJson(service, (ObjectNode) classNode.path(s),
89 - subjectFactory.createSubject(s))); 89 + subjectFactory.createSubject(s),
90 + subjectFactory.subjectKey()));
90 } 91 }
91 92
92 private static void consumeSubjectJson(NetworkConfigService service, 93 private static void consumeSubjectJson(NetworkConfigService service,
93 - ObjectNode subjectNode, Object subject) { 94 + ObjectNode subjectNode, Object subject, String subjectKey) {
94 subjectNode.fieldNames().forEachRemaining(c -> 95 subjectNode.fieldNames().forEachRemaining(c ->
95 - service.applyConfig(subject, service.getConfigClass(c), 96 + service.applyConfig(subject,
97 + service.getConfigClass(subjectKey, c),
96 (ObjectNode) subjectNode.path(c))); 98 (ObjectNode) subjectNode.path(c)));
97 } 99 }
98 100
......
...@@ -64,7 +64,7 @@ public class NetworkConfigManager implements NetworkConfigRegistry, NetworkConfi ...@@ -64,7 +64,7 @@ public class NetworkConfigManager implements NetworkConfigRegistry, NetworkConfi
64 // Secondary indeces to retrieve subject and config classes by keys 64 // Secondary indeces to retrieve subject and config classes by keys
65 private final Map<String, SubjectFactory> subjectClasses = Maps.newConcurrentMap(); 65 private final Map<String, SubjectFactory> subjectClasses = Maps.newConcurrentMap();
66 private final Map<Class, SubjectFactory> subjectClassKeys = Maps.newConcurrentMap(); 66 private final Map<Class, SubjectFactory> subjectClassKeys = Maps.newConcurrentMap();
67 - private final Map<String, Class<? extends Config>> configClasses = Maps.newConcurrentMap(); 67 + private final Map<ConfigIdentifier, Class<? extends Config>> configClasses = Maps.newConcurrentMap();
68 68
69 private final ListenerRegistry<NetworkConfigEvent, NetworkConfigListener> 69 private final ListenerRegistry<NetworkConfigEvent, NetworkConfigListener>
70 listenerRegistry = new ListenerRegistry<>(); 70 listenerRegistry = new ListenerRegistry<>();
...@@ -98,7 +98,7 @@ public class NetworkConfigManager implements NetworkConfigRegistry, NetworkConfi ...@@ -98,7 +98,7 @@ public class NetworkConfigManager implements NetworkConfigRegistry, NetworkConfi
98 public void registerConfigFactory(ConfigFactory configFactory) { 98 public void registerConfigFactory(ConfigFactory configFactory) {
99 checkNotNull(configFactory, NULL_FACTORY_MSG); 99 checkNotNull(configFactory, NULL_FACTORY_MSG);
100 factories.put(key(configFactory), configFactory); 100 factories.put(key(configFactory), configFactory);
101 - configClasses.put(configFactory.configKey(), configFactory.configClass()); 101 + configClasses.put(identifier(configFactory), configFactory.configClass());
102 102
103 SubjectFactory subjectFactory = configFactory.subjectFactory(); 103 SubjectFactory subjectFactory = configFactory.subjectFactory();
104 subjectClasses.putIfAbsent(subjectFactory.subjectKey(), subjectFactory); 104 subjectClasses.putIfAbsent(subjectFactory.subjectKey(), subjectFactory);
...@@ -160,8 +160,8 @@ public class NetworkConfigManager implements NetworkConfigRegistry, NetworkConfi ...@@ -160,8 +160,8 @@ public class NetworkConfigManager implements NetworkConfigRegistry, NetworkConfi
160 } 160 }
161 161
162 @Override 162 @Override
163 - public Class<? extends Config> getConfigClass(String configKey) { 163 + public Class<? extends Config> getConfigClass(String subjectKey, String configKey) {
164 - return configClasses.get(configKey); 164 + return configClasses.get(new ConfigIdentifier(subjectKey, configKey));
165 } 165 }
166 166
167 @Override 167 @Override
...@@ -270,4 +270,35 @@ public class NetworkConfigManager implements NetworkConfigRegistry, NetworkConfi ...@@ -270,4 +270,35 @@ public class NetworkConfigManager implements NetworkConfigRegistry, NetworkConfi
270 } 270 }
271 } 271 }
272 272
273 + private static ConfigIdentifier identifier(ConfigFactory factory) {
274 + return new ConfigIdentifier(factory.subjectFactory().subjectKey(), factory.configKey());
275 + }
276 +
277 + private static final class ConfigIdentifier {
278 + final String subjectKey;
279 + final String configKey;
280 +
281 + private ConfigIdentifier(String subjectKey, String configKey) {
282 + this.subjectKey = subjectKey;
283 + this.configKey = configKey;
284 + }
285 +
286 + @Override
287 + public int hashCode() {
288 + return Objects.hash(subjectKey, configKey);
289 + }
290 +
291 + @Override
292 + public boolean equals(Object obj) {
293 + if (this == obj) {
294 + return true;
295 + }
296 + if (obj instanceof ConfigIdentifier) {
297 + final ConfigIdentifier other = (ConfigIdentifier) obj;
298 + return Objects.equals(this.subjectKey, other.subjectKey)
299 + && Objects.equals(this.configKey, other.configKey);
300 + }
301 + return false;
302 + }
303 + }
273 } 304 }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onosproject.incubator.store.config.impl; 16 package org.onosproject.incubator.store.config.impl;
17 17
18 import com.fasterxml.jackson.databind.ObjectMapper; 18 import com.fasterxml.jackson.databind.ObjectMapper;
19 +import com.fasterxml.jackson.databind.node.ArrayNode;
19 import com.fasterxml.jackson.databind.node.BooleanNode; 20 import com.fasterxml.jackson.databind.node.BooleanNode;
20 import com.fasterxml.jackson.databind.node.DoubleNode; 21 import com.fasterxml.jackson.databind.node.DoubleNode;
21 import com.fasterxml.jackson.databind.node.JsonNodeFactory; 22 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
...@@ -81,7 +82,7 @@ public class DistributedNetworkConfigStore ...@@ -81,7 +82,7 @@ public class DistributedNetworkConfigStore
81 public void activate() { 82 public void activate() {
82 KryoNamespace.Builder kryoBuilder = new KryoNamespace.Builder() 83 KryoNamespace.Builder kryoBuilder = new KryoNamespace.Builder()
83 .register(KryoNamespaces.API) 84 .register(KryoNamespaces.API)
84 - .register(ConfigKey.class, ObjectNode.class, 85 + .register(ConfigKey.class, ObjectNode.class, ArrayNode.class,
85 JsonNodeFactory.class, LinkedHashMap.class, 86 JsonNodeFactory.class, LinkedHashMap.class,
86 TextNode.class, BooleanNode.class, 87 TextNode.class, BooleanNode.class,
87 LongNode.class, DoubleNode.class, ShortNode.class); 88 LongNode.class, DoubleNode.class, ShortNode.class);
......
...@@ -109,7 +109,7 @@ public class NetworkConfigWebResource extends AbstractWebResource { ...@@ -109,7 +109,7 @@ public class NetworkConfigWebResource extends AbstractWebResource {
109 @PathParam("configKey") String configKey) { 109 @PathParam("configKey") String configKey) {
110 NetworkConfigService service = get(NetworkConfigService.class); 110 NetworkConfigService service = get(NetworkConfigService.class);
111 return ok(service.getConfig(service.getSubjectFactory(subjectKey).createSubject(subject), 111 return ok(service.getConfig(service.getSubjectFactory(subjectKey).createSubject(subject),
112 - service.getConfigClass(configKey)).node()).build(); 112 + service.getConfigClass(subjectKey, configKey)).node()).build();
113 } 113 }
114 114
115 @SuppressWarnings("unchecked") 115 @SuppressWarnings("unchecked")
...@@ -183,7 +183,8 @@ public class NetworkConfigWebResource extends AbstractWebResource { ...@@ -183,7 +183,8 @@ public class NetworkConfigWebResource extends AbstractWebResource {
183 NetworkConfigService service = get(NetworkConfigService.class); 183 NetworkConfigService service = get(NetworkConfigService.class);
184 ObjectNode root = (ObjectNode) mapper().readTree(request); 184 ObjectNode root = (ObjectNode) mapper().readTree(request);
185 consumeSubjectJson(service, root, 185 consumeSubjectJson(service, root,
186 - service.getSubjectFactory(subjectKey).createSubject(subject)); 186 + service.getSubjectFactory(subjectKey).createSubject(subject),
187 + subjectKey);
187 return Response.ok().build(); 188 return Response.ok().build();
188 } 189 }
189 190
...@@ -209,7 +210,7 @@ public class NetworkConfigWebResource extends AbstractWebResource { ...@@ -209,7 +210,7 @@ public class NetworkConfigWebResource extends AbstractWebResource {
209 NetworkConfigService service = get(NetworkConfigService.class); 210 NetworkConfigService service = get(NetworkConfigService.class);
210 ObjectNode root = (ObjectNode) mapper().readTree(request); 211 ObjectNode root = (ObjectNode) mapper().readTree(request);
211 service.applyConfig(service.getSubjectFactory(subjectKey).createSubject(subject), 212 service.applyConfig(service.getSubjectFactory(subjectKey).createSubject(subject),
212 - service.getConfigClass(configKey), root); 213 + service.getConfigClass(subjectKey, configKey), root);
213 return Response.ok().build(); 214 return Response.ok().build();
214 } 215 }
215 216
...@@ -217,13 +218,15 @@ public class NetworkConfigWebResource extends AbstractWebResource { ...@@ -217,13 +218,15 @@ public class NetworkConfigWebResource extends AbstractWebResource {
217 SubjectFactory subjectFactory) { 218 SubjectFactory subjectFactory) {
218 classNode.fieldNames().forEachRemaining(s -> 219 classNode.fieldNames().forEachRemaining(s ->
219 consumeSubjectJson(service, (ObjectNode) classNode.path(s), 220 consumeSubjectJson(service, (ObjectNode) classNode.path(s),
220 - subjectFactory.createSubject(s))); 221 + subjectFactory.createSubject(s),
222 + subjectFactory.subjectKey()));
221 } 223 }
222 224
223 private void consumeSubjectJson(NetworkConfigService service, 225 private void consumeSubjectJson(NetworkConfigService service,
224 - ObjectNode subjectNode, Object subject) { 226 + ObjectNode subjectNode, Object subject,
227 + String subjectKey) {
225 subjectNode.fieldNames().forEachRemaining(c -> 228 subjectNode.fieldNames().forEachRemaining(c ->
226 - service.applyConfig(subject, service.getConfigClass(c), 229 + service.applyConfig(subject, service.getConfigClass(subjectKey, c),
227 (ObjectNode) subjectNode.path(c))); 230 (ObjectNode) subjectNode.path(c)));
228 } 231 }
229 232
...@@ -265,7 +268,7 @@ public class NetworkConfigWebResource extends AbstractWebResource { ...@@ -265,7 +268,7 @@ public class NetworkConfigWebResource extends AbstractWebResource {
265 @PathParam("configKey") String configKey) { 268 @PathParam("configKey") String configKey) {
266 NetworkConfigService service = get(NetworkConfigService.class); 269 NetworkConfigService service = get(NetworkConfigService.class);
267 service.removeConfig(service.getSubjectFactory(subjectKey).createSubject(subject), 270 service.removeConfig(service.getSubjectFactory(subjectKey).createSubject(subject),
268 - service.getConfigClass(configKey)); 271 + service.getConfigClass(subjectKey, configKey));
269 return Response.ok().build(); 272 return Response.ok().build();
270 } 273 }
271 274
......